From 0879a8fff2cb3652ce195482431f7231e94c986b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Bou=C3=A9?= Date: Fri, 7 Aug 2026 17:58:12 +0200 Subject: [PATCH 1/3] chore(deps): update minor and patch dependencies --- package-lock.json | 3895 +++++++++++++++++++-------------------------- 1 file changed, 1620 insertions(+), 2275 deletions(-) diff --git a/package-lock.json b/package-lock.json index c468915..0e77bc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -132,31 +132,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -168,14 +143,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", - "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -184,17 +159,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", @@ -423,13 +387,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.29.7" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -818,53 +782,28 @@ } }, "node_modules/@babel/traverse": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", - "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", + "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.7", + "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "dev": true, "license": "MIT", "dependencies": { @@ -1087,16 +1026,6 @@ "node": ">=v18" } }, - "node_modules/@commitlint/resolve-extends/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": { - "node": ">=8" - } - }, "node_modules/@commitlint/rules": { "version": "20.5.3", "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.3.tgz", @@ -1359,9 +1288,9 @@ } }, "node_modules/@cspell/dict-companies": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.11.tgz", - "integrity": "sha512-0cmafbcz2pTHXLd59eLR1gvDvN6aWAOM0+cIL4LLF9GX9yB2iKDNrKsvs4tJRqutoaTdwNFBbV0FYv+6iCtebQ==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.12.tgz", + "integrity": "sha512-mjiz/N3zWOCsz5VfwMUydSl7uW0OU9H2PnbCNc3RV44Vj6Q59CSp6EYGSGZQxrXU1gpsuZUrwr6QCjNjFOOg5A==", "dev": true, "license": "MIT" }, @@ -1401,9 +1330,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-data-science": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.14.tgz", - "integrity": "sha512-jl6Ds4u5u5JT+yY30pWQpAbdCHfy3lCcNkLbpL/AZKoUaLEoXbaYsps9xQtvD7DyaiXxiLZkdH2yHHXtoFtZyg==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.16.tgz", + "integrity": "sha512-M72mxv5asuAnORurz4iXRJ+Tw9XBq6eu7D2Ne7biP0Z1RciKGNxXWu9JycA/KlVvK1hAlKj/fANlXhuEWpXKFg==", "dev": true, "license": "MIT" }, @@ -1436,23 +1365,23 @@ "license": "MIT" }, "node_modules/@cspell/dict-en_us": { - "version": "4.4.35", - "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.35.tgz", - "integrity": "sha512-xWpxBCc/FzzMMo/A+0qwARVaIIhR0Ql8yhhv4rvsvg+GfQF+LG9yzg2GwTM5N2rjvzmM3nKuR9zxFZq2I6fJSg==", + "version": "4.4.36", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.36.tgz", + "integrity": "sha512-2yOhI/+7d1DbfvMljGW4jw8pLqDEsVmnvUXBOCFXtLU2BWgQkrqOJDCNseYjEiEbTp0OtdrWEWWPFSP1TNugQw==", "dev": true, "license": "MIT" }, "node_modules/@cspell/dict-en-common-misspellings": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.12.tgz", - "integrity": "sha512-14Eu6QGqyksqOd4fYPuRb58lK1Va7FQK9XxFsRKnZU8LhL3N+kj7YKDW+7aIaAN/0WGEqslGP6lGbQzNti8Akw==", + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.13.tgz", + "integrity": "sha512-00rpydUxKNWY2xxrSx+h46aNWLvbkJdd57SsnEFt24fbs1fROhXZ6XSQu+gQz/zNuiCvFi4Ro3ej9DLbEdWQmQ==", "dev": true, "license": "CC BY-SA 4.0" }, "node_modules/@cspell/dict-en-gb-mit": { - "version": "3.1.24", - "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.24.tgz", - "integrity": "sha512-Oowb/Uzkh7OmDRdCcETzMc9imEb4IpLlHJXoYjX8A8DS2X/54gqSjI915JFB8hKtFjBko5OM0BLQ+6cZhFEMmQ==", + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.25.tgz", + "integrity": "sha512-zGODptk24CMrXi49ieG2SUm94CKxEsVF0dYNF+1ZYH0MSsQDZ/PKDlrrbvtBqSupKdPSj0Z9sjOmMNfHHW9ZSg==", "dev": true, "license": "MIT" }, @@ -1555,9 +1484,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-k8s": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.12.tgz", - "integrity": "sha512-2LcllTWgaTfYC7DmkMPOn9GsBWsA4DZdlun4po8s2ysTP7CPEnZc1ZfK6pZ2eI4TsZemlUQQ+NZxMe9/QutQxg==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.13.tgz", + "integrity": "sha512-ELGkS13k7K/NEfVimBSrxVTfqXvOF/Kvxj4I62YxRm8bvHbfoXgrGaOx28lPiNRz+dmu+yYtvuXbnURKtYbC6g==", "dev": true, "license": "MIT" }, @@ -1624,9 +1553,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-npm": { - "version": "5.2.41", - "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.41.tgz", - "integrity": "sha512-To3xsfRmMBYVXtWVEdUgV35M9a/JZ54dSuoY6m6D3uHKKL3I326Wmy4xifZ3PU8MQaWhyEH7zbIcUEtKwTQMcA==", + "version": "5.2.43", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.43.tgz", + "integrity": "sha512-H2gYwtu59dNO9662Uq0usfuhyNd7lZJE1C61a/UXcpRyWWSrTo2Bz+vwGYp1bXZ1LmjXadqvwJ8ArFlGdiadNQ==", "dev": true, "license": "MIT" }, @@ -1652,13 +1581,13 @@ "license": "MIT" }, "node_modules/@cspell/dict-python": { - "version": "4.2.27", - "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.27.tgz", - "integrity": "sha512-Rj6xQgYS4X6ienjgAZF+njA0GRY4oSPouJWv0vfikCTn6EWlfk0V6Dy1HP3Migj1O+IC2NmespgVq+BZNSp8OA==", + "version": "4.2.29", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.29.tgz", + "integrity": "sha512-OnEt1a35iuQzc2Ize1qU/43ZyF10urRKAm+mlTz++vnAgDLBHpKfWakpSK50nyL5/1WvyQ8BaMjb52MBLEpTeA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/dict-data-science": "^2.0.14" + "@cspell/dict-data-science": "^2.0.16" } }, "node_modules/@cspell/dict-r": { @@ -1697,9 +1626,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-software-terms": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.2.2.tgz", - "integrity": "sha512-0CaYd6TAsKtEoA7tNswm1iptEblTzEe3UG8beG2cpSTHk7afWIVMtJLgXDv0f/Li67Lf3Z1Jf3JeXR7GsJ2TRw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.2.4.tgz", + "integrity": "sha512-z6y/TGH3QNf5wB4pVvN/P3GfFEW/Whf6QAekNsIn06VKl95dnamfpkPWqV8rEtCixQFaKalb5+y9hRQXH3XQ1g==", "dev": true, "license": "MIT" }, @@ -1725,9 +1654,9 @@ "license": "MIT" }, "node_modules/@cspell/dict-terraform": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.1.3.tgz", - "integrity": "sha512-gr6wxCydwSFyyBKhBA2xkENXtVFToheqYYGFvlMZXWjviynXmh+NK/JTvTCk/VHk3+lzbO9EEQKee6VjrAUSbA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.1.4.tgz", + "integrity": "sha512-Ere42ilvMFvQA4GlcN0OKlruMPR6EsvaB+iTHzj2xc+NJGRK64V7yApUcWrOrSgTiM/vhWXPIsK3OMfiAiNdmA==", "dev": true, "license": "MIT" }, @@ -1819,22 +1748,33 @@ "node": ">=12" } }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", + "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", "dev": true, "license": "MIT", "optional": true, @@ -1843,9 +1783,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, "license": "MIT", "optional": true, @@ -1854,25 +1794,28 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -1920,6 +1863,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -1931,22 +1881,14 @@ "concat-map": "0.0.1" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/@eslint/eslintrc/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", - "dependencies": { - "ms": "^2.1.3" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 4" } }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { @@ -1969,13 +1911,6 @@ "node": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", @@ -2051,6 +1986,13 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -2062,24 +2004,6 @@ "concat-map": "0.0.1" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -2093,13 +2017,6 @@ "node": "*" } }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2205,19 +2122,6 @@ } } }, - "node_modules/@inquirer/core/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@inquirer/editor": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.2.2.tgz", @@ -2497,57 +2401,6 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/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, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", @@ -2564,24 +2417,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "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", @@ -2679,16 +2514,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/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": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", @@ -2919,49 +2744,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "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": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/reporters/node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/@jest/schemas": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", @@ -3006,17 +2788,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@jest/test-result": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", @@ -3075,17 +2846,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/transform/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@jest/types": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", @@ -3116,17 +2876,6 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", @@ -3138,17 +2887,6 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/remapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -3160,21 +2898,21 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@js-sdsl/ordered-map": { @@ -3188,22 +2926,25 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", - "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.3" }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, "node_modules/@noble/hashes": { @@ -3258,9 +2999,9 @@ } }, "node_modules/@oxc-parser/binding-android-arm-eabi": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.137.0.tgz", - "integrity": "sha512-KDs+0VPdEmasOkpuJHW9V5WCF+cvYdMQv2Jd+aJXt+cxIx12NToRQRbXaRwUEDsZw+/jMk81Ve8ZFbjUkJTOwA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.142.0.tgz", + "integrity": "sha512-ZiRGDutGsv1G6bL/ozy/koC0Sv39T1DqyoC4KD1DOy9ZoACm1O5UWhEK2c02Qdk+4lfLVkvFa/mQ0fm/4h1BtQ==", "cpu": [ "arm" ], @@ -3275,9 +3016,9 @@ } }, "node_modules/@oxc-parser/binding-android-arm64": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.137.0.tgz", - "integrity": "sha512-WhALNzfy3x/RfC6bsqX+csavuUY0yHHE7XfgPE5M542uhoBZUUoGTPG+nkMbGoG4+gcfss5s7urMyn5QBHu0sw==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.142.0.tgz", + "integrity": "sha512-WZkvGRLNQTz8lR9zP5nLjUdlroRCopBu3g9zF1p/laE6DzT1UbQo8Rdz5MWhaJUPYg/6gp+jo7HUgsyKaN1FtQ==", "cpu": [ "arm64" ], @@ -3292,9 +3033,9 @@ } }, "node_modules/@oxc-parser/binding-darwin-arm64": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.137.0.tgz", - "integrity": "sha512-bFPr5hgmNMOMoyPTGtdsK4Ug21RovIPojRMgDDhSp1LtCnc/DkLwGONKjgRjszg677RlGnkYSviQ8hHaUPOVYA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.142.0.tgz", + "integrity": "sha512-l4khS8LQOOVYsGRVARo1gSaCT/aBSceUVXgtovWc2+drnxVuDr082WA3OCHVdVzIz5JIrP/y9CWsSKxBDNmYGg==", "cpu": [ "arm64" ], @@ -3309,9 +3050,9 @@ } }, "node_modules/@oxc-parser/binding-darwin-x64": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.137.0.tgz", - "integrity": "sha512-CL5dMm1asqXIDZHg14FLxj3Mc36w8PI7xCWh1uA4is6z8g2XrIILoTcQYOxDbwzuk34RDPX5IAGUxZr6LA9KAg==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.142.0.tgz", + "integrity": "sha512-QBsNF3nqlXmcH2B1YOPqQYmCJoy4HuIjUxGbBO/k5JAJUl68ghU2psRY2zPk+RyBaWqKP/qfL4oaFgEMCdwskA==", "cpu": [ "x64" ], @@ -3326,9 +3067,9 @@ } }, "node_modules/@oxc-parser/binding-freebsd-x64": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.137.0.tgz", - "integrity": "sha512-79h8rYGnSlKPGWo7mHr2ixO6ea7aW8B0CT965SZ8SLbNnCOH5aOYBTeVXUY6eMvEaiLyWr8Skuiugr5pDYgLGw==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.142.0.tgz", + "integrity": "sha512-b7Q7m4Cqc6XqNhri3R+QhU+GVy646Pn+bkdhrDdWym/Fdi0ZUa+d73H9dm5H91JtbtAQ/z1d8XKMW3oOV8a4tQ==", "cpu": [ "x64" ], @@ -3343,9 +3084,9 @@ } }, "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.137.0.tgz", - "integrity": "sha512-ASgmlSimhGyr0lksgVIo6hibz1obnDq4qJbiMX/AzltfgPnanRrzG1Q+23g8ljOHOjv6dsznkUuCYL3gg0sY1Q==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.142.0.tgz", + "integrity": "sha512-3riVS5IhdH3uCZj1Y9ftDQlR0dvLsIlw/edrRqk8JhgNd5K0XSs+UBtgh50N13CAlW9/TXj6sVGXaKNBocd0Yg==", "cpu": [ "arm" ], @@ -3360,9 +3101,9 @@ } }, "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.137.0.tgz", - "integrity": "sha512-AU2J9aa22Sx32wRGnDjybOU9TQXXQUud5sdUi+ZB0XxwM8aToWLweV+yA0wlQm0yIUVqljquqoHCYEq9II8gJQ==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.142.0.tgz", + "integrity": "sha512-NmXUOpgpTSkhl795TiXmWppTwmSJ92RC1qvD6e4XOF+slgmo3e6Ah+kEu+6AN8s7NAOEwqGmir58MgSQSWmBSA==", "cpu": [ "arm" ], @@ -3377,13 +3118,16 @@ } }, "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.137.0.tgz", - "integrity": "sha512-GdEtiG89yMr7XkUGxifgodXEEm2f+xW2f9CpDjlgAnBOwhTmrpQMvhOGobLVKUyzf/qHBXW16smk5zbF3nZU6w==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.142.0.tgz", + "integrity": "sha512-gc0EXsKtXgerujmU2Bql3u1L1HsSQ2774R83idq/FoNMPVV/RY/1ErFsvnit7KoiP/sLvzQixeUo4Ut0ic0wmw==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3394,13 +3138,16 @@ } }, "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.137.0.tgz", - "integrity": "sha512-EGJ+Bs8iXx8KBH8DQ5BLoEm5lnHaYjlh4/8j8vFhrr/6z4tqONy5BZDzLpKmmNWlN6Hlc5r8YOuBVHqZ9vRFEQ==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.142.0.tgz", + "integrity": "sha512-F2XvmWSE0uWpie+jHKKIFgdVOe9ypGhkEZxKx5DuW215K6cbAC274yYaPkcM7EqY4Df3Weyhpcz3lsURyH2LVg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3411,13 +3158,16 @@ } }, "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.137.0.tgz", - "integrity": "sha512-vzFUQENy/fnbSe5DZWovq6tIBc1uhuMztanSW6rz1e9WdQE4gHwYuD7ZII6JnrJifd1R3RSoqiZbgRFlVL2tYQ==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.142.0.tgz", + "integrity": "sha512-wLMbT21U/QxknQsk+VvNF0b9D2/aGWhcaQQQ+VYlE8FwD5+GoWZIPPXNzyHmkYyhm0KB3itL+TBavjMatqNnYA==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3428,13 +3178,16 @@ } }, "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.137.0.tgz", - "integrity": "sha512-SfVI14HBQs9gtLcUD5hTt5hsNbdrqSUNg9S8muN+LhVQ5nf1WwH3hAoK6B9NKgdYgWAQSXFXGiiBedQ4r/BKuw==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.142.0.tgz", + "integrity": "sha512-+G8F/4ckwT7FCJV4H2bt09xEzJbjNCfuL4Sp1AYNaFtFMVtgIGMuJlteT82U+K0UIZ/DzAR/LDlMFnEuajG7Kw==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3445,13 +3198,16 @@ } }, "node_modules/@oxc-parser/binding-linux-riscv64-musl": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.137.0.tgz", - "integrity": "sha512-e7Ppy4FCIFNQxT/ikSeIWFoQ0l+N9vgtRBtLcyZXeolTzApyVoPqEXsYPrcdM/9i0Bwk8knvYd37vaEMxHyi6g==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.142.0.tgz", + "integrity": "sha512-hTsHtTLxMAfCo+rpF5K3qZJKW2NpPN/CHd4mYB3y7XlSdspHkd2gehDIofP64AacA9nWQw2tY3O7wR6UY8IVOA==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3462,13 +3218,16 @@ } }, "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.137.0.tgz", - "integrity": "sha512-Bho5qFwdhqsIFR7gipYEUlqvi3SRrY8sugxXig380MIaakBB1PyU9+7dBiBVScfImTNWhijUxdBwqrprGdq5WA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.142.0.tgz", + "integrity": "sha512-6y7qYY3TCUDYjqswImdTGl92y+KA/80twALegQPN27kfY+bG7Ib1+L3jbmrCZQx6wrVnai9IPsEZp07I0hx7JQ==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3479,13 +3238,16 @@ } }, "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.137.0.tgz", - "integrity": "sha512-36mGWtg7PyFzjJwGDkH6/F4o2nIDEoKXLPr/X/lwqklkomQwJJt1I5GJVmGhovUEmgPK5WAeAZMqlFCehwiy9Q==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.142.0.tgz", + "integrity": "sha512-i69kAWU+2LgoH5bR+zWiiu+UzAw7Oxkwv7COeJTeY19pn4e70nKQcr9Pm6cL2Z0Z54d+gl9qADlK/0yyuCPiBA==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3496,13 +3258,16 @@ } }, "node_modules/@oxc-parser/binding-linux-x64-musl": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.137.0.tgz", - "integrity": "sha512-/Jqx6+N7A44n2BdvUr7pXhVr2vFjs6WGH3unZRczwrfiH0H1zY0QwKQMG/dtRiTlKGDKGukznPT8lx84/oEsZg==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.142.0.tgz", + "integrity": "sha512-4SQs678MmjYVrmhAgCWD4o0vpaFszXw9xLX5p2Z9MMFcltxiLkA88wQjh80YHjPrXtpyZ2CWI5m+1yNKM0m2Pw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3513,9 +3278,9 @@ } }, "node_modules/@oxc-parser/binding-openharmony-arm64": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.137.0.tgz", - "integrity": "sha512-9Uj0qHNNl+OgT1UTGwF7ixIXU6T1u2SbMidmgPy/h1h/fl2gRS6YpAxxY1gwHofcWjoTwkoMFd8xs5Vuj6GOFA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.142.0.tgz", + "integrity": "sha512-YHpx9N7Ln3a++Tc8rv+H7mrK1zyJQOAwCFg8LZ3lTs1T5afGWeZrLPhPT9HLnIwSjCyJqPWVMIrMxbjcmBr2oQ==", "cpu": [ "arm64" ], @@ -3530,9 +3295,9 @@ } }, "node_modules/@oxc-parser/binding-wasm32-wasi": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.137.0.tgz", - "integrity": "sha512-gW2vfkytNGgMVADiuzdvOfw0mWG9za20F/1fCJsif5aBMAvWJTSbpIXbIe0XkOe0VENk+PadpQ7cZgUy2sUJcA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.142.0.tgz", + "integrity": "sha512-3pLDyY3+oogW73RM5uehNgAiR/Xfb7fvO2Q1Z1gIqZ2+50XDVQmBVlRkHXZTU4gKnQHpwETNsYQVsJ3joVB2iA==", "cpu": [ "wasm32" ], @@ -3540,52 +3305,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.11.1", - "@emnapi/runtime": "1.11.1", - "@napi-rs/wasm-runtime": "^1.1.5" + "@emnapi/core": "1.11.2", + "@emnapi/runtime": "1.11.2", + "@napi-rs/wasm-runtime": "^1.1.6" }, "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", - "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@oxc-parser/binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@oxc-parser/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@oxc-parser/binding-win32-arm64-msvc": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.137.0.tgz", - "integrity": "sha512-x+pFANF0yL5uK/6T7lu6SlR5qid6sp//eZXKLq5iNsIE+EQg6EaS8/wsW7E91nXXjpnPhSoMOHXShSVhGRdn8w==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.142.0.tgz", + "integrity": "sha512-Had/VeVY28Oyb0K+Q4FV8KCzoBycIh93oDK6pCbya9lkzdq+ikMHMgBubsdqqlybjJmQRawCQRrnBRHyQwYvcQ==", "cpu": [ "arm64" ], @@ -3600,9 +3331,9 @@ } }, "node_modules/@oxc-parser/binding-win32-ia32-msvc": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.137.0.tgz", - "integrity": "sha512-sQUqym80PFi6McRsIqfJrSu2JrSClEZIXXD+/FjAFoULEKzOPsldIdFBG96xdX8aVMzCNQ9792FPx3MfkEIrFA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.142.0.tgz", + "integrity": "sha512-GGi3+YphVHavvgs6gum2UXoNCqzHAmPt/nXkn8ZQZstV2Q1qZD1Mn8fz/nWrDkefHQtrG/+1/XrbMxsBTo6Svw==", "cpu": [ "ia32" ], @@ -3617,9 +3348,9 @@ } }, "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.137.0.tgz", - "integrity": "sha512-2AsevxlvNN4WKxpEn3RtqD5zbqMaXF+T7JXblsP4gVuY+vC9dXS4ED/PwfRCliFqoeisYS3Iro4DHzxr0TEvVA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.142.0.tgz", + "integrity": "sha512-Ny/Wv4Us1LGC/ljwNTp+Hx3r/pH15EFfeDF0p+n898gt+TtRd6C9SccHcuUhDiNTb8s5tt7jdeAMDRQZ4Vq6hg==", "cpu": [ "x64" ], @@ -3634,9 +3365,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz", - "integrity": "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.142.0.tgz", + "integrity": "sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==", "dev": true, "license": "MIT", "funding": { @@ -3644,9 +3375,9 @@ } }, "node_modules/@oxc-resolver/binding-android-arm-eabi": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.21.3.tgz", - "integrity": "sha512-eNU11A2WNizh04v3uyaJCootrHIaS0B9aHYXvAvVnPNk4xYSjMUjHnhQ6dewPN2MRYDskV85d1N0Aw0WNWhcyg==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.24.2.tgz", + "integrity": "sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==", "cpu": [ "arm" ], @@ -3658,9 +3389,9 @@ ] }, "node_modules/@oxc-resolver/binding-android-arm64": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.21.3.tgz", - "integrity": "sha512-8Q+ZjTLvn2dIcWsrmhdrEihm7q+ag/k+mkry7Z+t0QbbHaVxXQfvH9AewyVMh/WrpEKhQ3DDgx9fYbqeCpeOEw==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.24.2.tgz", + "integrity": "sha512-cl4icWaZFnLdg8m6qtnh5rBMuGbxc/ptStFHLeCNwr+2cZjkjNwQu/jYRS0CHlnPecOJMpuS5M6/BH+0J/YkEg==", "cpu": [ "arm64" ], @@ -3672,9 +3403,9 @@ ] }, "node_modules/@oxc-resolver/binding-darwin-arm64": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.21.3.tgz", - "integrity": "sha512-wkh0qKZGHXVUDxFw3oA1TXnU2BDYY/r775oJflGeIr8uDPPoN2pk8gijQIzYRT6hoql/lg3+Tx/SaTn9e2/aGg==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.24.2.tgz", + "integrity": "sha512-At29QEMF6HajbQvgY8K6OXnHD1x9rad74xBEfmCB6ZqCGsdq75aK7tOYcTbOanMy8qdIBrfL3SMr3p/lfSlb9w==", "cpu": [ "arm64" ], @@ -3686,9 +3417,9 @@ ] }, "node_modules/@oxc-resolver/binding-darwin-x64": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.21.3.tgz", - "integrity": "sha512-HbNc23FAQYbuyDV2vBWMez4u4mrsm5RAkniGZAWqr6lYZ3N4beeqIb776jzwRl8qL2zRhHVXpUj97X0QgogVzg==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.24.2.tgz", + "integrity": "sha512-A5Kqr1EUj4oIL5CF4WRssq/o5P0Y11cwoFouMRmQ7YnC/A8V93nv1nb7aSU8HwcgmXropjLNkVTl4MN87cu28Q==", "cpu": [ "x64" ], @@ -3700,9 +3431,9 @@ ] }, "node_modules/@oxc-resolver/binding-freebsd-x64": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.21.3.tgz", - "integrity": "sha512-K6xNsTUPEUdfrn0+kbMq5nOUB5w1C5pavPQngt4TM2FpN91lP0PBe2srSpamb4d69O7h86oAi/qWX/kZNRSjkw==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.24.2.tgz", + "integrity": "sha512-R5xkRBRRz7ceH/P5Jrc6G7FmdUdgpLYyESFAUDVTNQ9K0sGPxcp4ljiwEwEqsvNcQ4sYbMRrWcHHBCu7ksAJVw==", "cpu": [ "x64" ], @@ -3714,9 +3445,9 @@ ] }, "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.21.3.tgz", - "integrity": "sha512-VcFmOpcpWX1zoEy8M58tR2M9YxM+Z9RuQhqAx5q0CTmrruaP7Gveejg75hzd/5sg5nk9G3aLALEa3hE2FsmmTQ==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.24.2.tgz", + "integrity": "sha512-k/RuYL4L/R58IBn3wT5ma3Wh4k62bp1eYCFRWCmMsasUOqL+H6sW0VGFadEzKWXFFlz+2uIMoeMk9ySSZJHgbg==", "cpu": [ "arm" ], @@ -3728,9 +3459,9 @@ ] }, "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.21.3.tgz", - "integrity": "sha512-quVoxFLBy43hWaQbbDtQNRwAX5vX76mv7n64icAtQcJ3eNgVeblqmkupF/hAneNthdqSlnd1sTjb3aQSaDPaCQ==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.24.2.tgz", + "integrity": "sha512-bnHAak3ujYfH5pKk4NieFNbvYvernfoQDgwLddbZ3OtMYrem87/qjlA+u+aKG0oZcqSLGCful/6/CEA+aeAgaA==", "cpu": [ "arm" ], @@ -3742,13 +3473,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.21.3.tgz", - "integrity": "sha512-X0AqNZgcD07Q4V3RDK18/vYOj/HQT/FnmEFGYS2jTWqY7JO13ryE3TEs3eAIgUJhBnNkpEaiXqz3VK8M7qQhWQ==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.24.2.tgz", + "integrity": "sha512-vDT3KHgzYp47gmtNOqL2VNhCyl5Zv643eyxm//A68J8DeUGXrvD1pZFiaT4jSfe+RInfnn1R2yVHye4enx6RnA==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3756,13 +3490,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-arm64-musl": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.21.3.tgz", - "integrity": "sha512-YkaQnaKYdbuaXvRt5Qd0GpbihzVnyfR6z1SpYfIUC6RTu4NF7lDKPjVkYb+jRI2gedVO2rVpN35Y6akG6ud4Lw==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.24.2.tgz", + "integrity": "sha512-+kMlQvbzfyEYtu5FcjE4p+ttBLpKW4d/AsAsuE69BxV6V4twZJeIQZFfD8gh/wqglY0MkPSezWXQH0jBV13MUw==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3770,13 +3507,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.21.3.tgz", - "integrity": "sha512-gB9HwhrPiFqUzDeEq+y/CgAijz1YdI6BnXz5GaH2Pa9cWdutchlkGFAiAuGb/PjVQpiK6NFKzFuztxrweoit7A==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.24.2.tgz", + "integrity": "sha512-shjfMhmZ3gq9fv/w7bi3PnZlgOPG+2QAOFf0BJF0EgBSIGZ6PMLN2zbGEblTUYB/NKVDRyYhE2ff3dJ1QqNPkA==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3784,13 +3524,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.21.3.tgz", - "integrity": "sha512-zjDWBlYk8QGv0H8dsPUWqkfjYIIjG2TvspGkzXL0eImbgxtZorA/klKeHyolevoT3Kvbi+1iMr9Lhrh7jf54Og==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.24.2.tgz", + "integrity": "sha512-zGelwFR5oRo+b69k8Lrzun86DyUHzfKN6cnjbR9l7Z7NIRznOE/2ZvPa1IUKqAL2PzAXOdwkfVqNvO1H2RlpAw==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3798,13 +3541,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.21.3.tgz", - "integrity": "sha512-4UfsQvacV388y1zpXL7C1x1FNYaV52JtuNRiuzrfQA2z1z6ElVrsidkGsrvQ5EgeSq1Pj7kaKqrgGkvFuxJ/tw==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.24.2.tgz", + "integrity": "sha512-qxZ1SWCXJY0eyhAlP6Lmo9F2Nrtx7EkYj9oCgL8apDPCwXwCEDA2U697bbT81JIc2IrVjxO4KX6WU2N+oN9Z4w==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3812,13 +3558,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.21.3.tgz", - "integrity": "sha512-b5uH+HKH0MP5mNBYaK75SKsJbw52URqrx2LavYdq6wb0l3ExAG5niYRP9DWUNHdKilpaBVM2bXk9HNWrH3ew7Q==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.24.2.tgz", + "integrity": "sha512-sGCecF3cx2DFlH4t/z7ApnOnXqN48p5p5mlHDEnHTAukQa2P+qMVE4CwyWE9W+q/m3QJ7kKfGrIjax31f44oFQ==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3826,13 +3575,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-x64-gnu": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.21.3.tgz", - "integrity": "sha512-PjYlmilBpNRh2ntXNYAK3Am5w/nPfEpnU/96iNx7CI8EzAn12J4JRiec63wHJTH31nLoCNxBg/829pN+3CfG3Q==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.24.2.tgz", + "integrity": "sha512-k/VlMMcSzMlahb3/fENM4rTlsJ0s3fFROA0KXPBmKggqmTSaE383sl8F3KCOXPLmVsYfW6hCitMhXCEtNeZxxg==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3840,13 +3592,16 @@ ] }, "node_modules/@oxc-resolver/binding-linux-x64-musl": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.21.3.tgz", - "integrity": "sha512-QTBAb7JuHlZ7JUEyM8UiQi2f7m/L4swBhP2TNpYIDc9Wp/wRw1G/8sl6i13aIzQAXH7LKIm294LeOHd0lQR8zA==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.24.2.tgz", + "integrity": "sha512-8hbnZyNi97b/8wapYaIF9+t9GmZKBW2vunaOc3h9HGJptH7b7XpvZqOTBSm/MpTjr7H497BlgOaSfLUdhmy2bw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3854,9 +3609,9 @@ ] }, "node_modules/@oxc-resolver/binding-openharmony-arm64": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.21.3.tgz", - "integrity": "sha512-4j1DFwjwv36ec9kds0jU/ucQ5Ha4ERO/H95BxR5JFf0kqUUAJ1kwII7XhTc1vZrkdJkvLGC9Q2MbpObpum8RBg==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.24.2.tgz", + "integrity": "sha512-MvyGik3a6pVgZ0t/kWlbmFxFLmXQJwgLsY2eYFHLpy0wGwRbfzeIGgDwQ3kXqE30z+kSXennRkCrT7TUvkptNg==", "cpu": [ "arm64" ], @@ -3868,9 +3623,9 @@ ] }, "node_modules/@oxc-resolver/binding-wasm32-wasi": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.21.3.tgz", - "integrity": "sha512-i8oluoel5kru/j1WNrjmQSiA3GQ7wvIYVR1IwIoZtKogAhya2iub+ZKIeSIkcJOrnzQ18Tzl/F+kL3fYOxZLvA==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.24.2.tgz", + "integrity": "sha512-vHcssMPwO08RTvj/c0iOBz90attxyG3wQJ0dTcyEQK43LRpcdLWZlV5feBhv6Isn6ahbQIzHbCgfa81+RiML0Q==", "cpu": [ "wasm32" ], @@ -3878,52 +3633,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.11.0", - "@emnapi/runtime": "1.11.0", - "@napi-rs/wasm-runtime": "^1.1.5" + "@emnapi/core": "1.11.2", + "@emnapi/runtime": "1.11.2", + "@napi-rs/wasm-runtime": "^1.1.6" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@oxc-resolver/binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz", - "integrity": "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@oxc-resolver/binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz", - "integrity": "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@oxc-resolver/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.21.3.tgz", - "integrity": "sha512-M/8dw8dD6aOs+NlPJax401CZB9I7Aut84isQLgALGGwke4Afvw+/7yYhZb94yXf6t2sPLhQLmSmtSV+2FhsOWg==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.24.2.tgz", + "integrity": "sha512-uokJqro2iBqkFvJdKQLP7d8/BUmFwESQFVmIJUQKj1Xn1a/LysJoe1vmeECLF5b3jsV8CAL5sEMJXX6SdK9Nhg==", "cpu": [ "arm64" ], @@ -3935,9 +3656,9 @@ ] }, "node_modules/@oxc-resolver/binding-win32-x64-msvc": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.21.3.tgz", - "integrity": "sha512-H7BCt/VnS9hnmMp42eGhZ99izSCRvlnWwy/N71K1/J8QoExwY4262Z8QiEkMDtduRJrztayDxETTckmUuAVL9Q==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.24.2.tgz", + "integrity": "sha512-UqGPmo56KDfLlfXFAFIrNflHT8tFxWGEivWg3Zeyp4Uy2NlKN1FGPr6/BxcLGG3+kZ6Wp14g5Uj+n71boqZfiw==", "cpu": [ "x64" ], @@ -4076,9 +3797,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "dev": true, "license": "MIT" }, @@ -4172,27 +3893,21 @@ "node": ">=20.0.0" } }, - "node_modules/@stryker-mutator/core/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@stryker-mutator/core/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "node_modules/@stryker-mutator/core/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": "20 || >=22" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/@stryker-mutator/core/node_modules/chalk": { @@ -4208,39 +3923,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@stryker-mutator/core/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@stryker-mutator/core/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@stryker-mutator/core/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, "node_modules/@stryker-mutator/instrumenter": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-9.6.1.tgz", @@ -4265,6 +3947,19 @@ "node": ">=20.0.0" } }, + "node_modules/@stryker-mutator/instrumenter/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@stryker-mutator/jest-runner": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@stryker-mutator/jest-runner/-/jest-runner-9.6.1.tgz", @@ -4284,6 +3979,19 @@ "@stryker-mutator/core": "9.6.1" } }, + "node_modules/@stryker-mutator/jest-runner/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@stryker-mutator/typescript-checker": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@stryker-mutator/typescript-checker/-/typescript-checker-9.6.1.tgz", @@ -4303,6 +4011,19 @@ "typescript": ">=3.6" } }, + "node_modules/@stryker-mutator/typescript-checker/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@stryker-mutator/util": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-9.6.1.tgz", @@ -4311,9 +4032,9 @@ "license": "Apache-2.0" }, "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", "dev": true, "license": "MIT" }, @@ -4405,9 +4126,9 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -4426,12 +4147,12 @@ } }, "node_modules/@types/cookie-parser": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.7.tgz", - "integrity": "sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.10.tgz", + "integrity": "sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg==", "dev": true, "license": "MIT", - "dependencies": { + "peerDependencies": { "@types/express": "*" } }, @@ -4443,9 +4164,9 @@ "license": "MIT" }, "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "dev": true, "license": "MIT", "dependencies": { @@ -4453,9 +4174,9 @@ } }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -4583,9 +4304,9 @@ "license": "MIT" }, "node_modules/@types/morgan": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", - "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", + "integrity": "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==", "dev": true, "license": "MIT", "dependencies": { @@ -4593,9 +4314,9 @@ } }, "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/multer": { @@ -4609,18 +4330,18 @@ } }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@types/nodemailer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.0.tgz", - "integrity": "sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz", + "integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==", "dev": true, "license": "MIT", "dependencies": { @@ -4663,9 +4384,9 @@ } }, "node_modules/@types/ssh2": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.1.tgz", - "integrity": "sha512-ZIbEqKAsi5gj35y4P4vkJYly642wIbY6PqoN0xiyQGshKUGXR9WQjF/iF9mXBQ8uBKy3ezfsCkcoHKhd0BzuDA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.5.tgz", + "integrity": "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4673,9 +4394,9 @@ } }, "node_modules/@types/ssh2/node_modules/@types/node": { - "version": "18.19.64", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", - "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, "license": "MIT", "dependencies": { @@ -4697,9 +4418,9 @@ "license": "MIT" }, "node_modules/@types/superagent": { - "version": "8.1.10", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.10.tgz", - "integrity": "sha512-nbt4IWXABhW0jGmmpRzCFNlbmwCTzZ2gTUsNIr+X+ItdqPms+PAJZbWsNzpS2USqXjcoNLQcO6nXo60zcPQiIg==", + "version": "8.1.11", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.11.tgz", + "integrity": "sha512-KA7srSW/HENDtOw9DOqaFLgWuMqN9WgjEw62lh9dpvRaZDkhdOkazASd7X7i2eMUYLHa1U37ZttnePsH5zTDHw==", "dev": true, "license": "MIT", "dependencies": { @@ -4710,9 +4431,9 @@ } }, "node_modules/@types/supertest": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.0.tgz", - "integrity": "sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.1.tgz", + "integrity": "sha512-4CbBvoYVLHL7+yhbYrZET0vsvuyXTC05aRe7dNQkwMzm56auceoy6Yu3K50uZmwfHna1os3CMSgM/3QVkUtPTw==", "dev": true, "license": "MIT", "dependencies": { @@ -4721,9 +4442,9 @@ } }, "node_modules/@types/validator": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.1.tgz", - "integrity": "sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA==", + "version": "13.15.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", + "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", "license": "MIT" }, "node_modules/@types/ws": { @@ -4754,21 +4475,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz", - "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", + "integrity": "sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/type-utils": "8.5.0", - "@typescript-eslint/utils": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/type-utils": "8.66.0", + "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4778,27 +4498,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.66.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz", - "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.66.0.tgz", + "integrity": "sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4808,48 +4524,41 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", + "integrity": "sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@typescript-eslint/tsconfig-utils": "^8.66.0", + "@typescript-eslint/types": "^8.66.0", + "debug": "^4.4.3" }, "engines": { - "node": ">=6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz", - "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", + "integrity": "sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0" + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4859,18 +4568,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz", - "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", + "integrity": "sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/utils": "8.5.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4878,41 +4581,39 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", + "integrity": "sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/utils": "8.66.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">=6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/types": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz", - "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.66.0.tgz", + "integrity": "sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==", "dev": true, "license": "MIT", "engines": { @@ -4924,20 +4625,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz", - "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", + "integrity": "sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/project-service": "8.66.0", + "@typescript-eslint/tsconfig-utils": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4946,48 +4648,21 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz", - "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.66.0.tgz", + "integrity": "sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4997,18 +4672,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz", - "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", + "integrity": "sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.5.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.66.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5018,10 +4694,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.2.tgz", - "integrity": "sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", "dev": true, "license": "ISC" }, @@ -5131,6 +4820,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5145,6 +4837,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -5159,6 +4854,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5173,6 +4871,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -5187,6 +4888,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5201,6 +4905,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5215,6 +4922,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -5229,6 +4939,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5243,6 +4956,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5257,6 +4973,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -5296,6 +5015,40 @@ "node": ">=14.0.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", @@ -5340,12 +5093,18 @@ }, "node_modules/@variamosple/variamos-security": { "version": "0.0.15", + "resolved": "https://registry.npmjs.org/@variamosple/variamos-security/-/variamos-security-0.0.15.tgz", + "integrity": "sha512-NfuXvff8ztAu5PNc9aHdVKsL994qx4ESsowEQq/yuvaDK8cWSgYQUFMcuLkrB8daNOXdRiMFytRztdXGMSos1w==", "license": "MIT", "dependencies": { "@variamosple/variamos-security": "file:", "node-jose": "^2.2.0" } }, + "node_modules/@variamosple/variamos-security/node_modules/@variamosple/variamos-security": { + "resolved": "node_modules/@variamosple/variamos-security", + "link": true + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -5359,31 +5118,6 @@ "node": ">= 0.6" } }, - "node_modules/accepts/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/acorn": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", @@ -5441,44 +5175,21 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "debug": "4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 6.0.0" } }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "dev": true, "license": "MIT", "dependencies": { @@ -5532,12 +5243,16 @@ } }, "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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -5569,6 +5284,19 @@ "node": ">= 8" } }, + "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": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -5635,85 +5363,37 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", - "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz", + "integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", + "form-data": "^4.0.6", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, - "node_modules/axios/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/axios/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/babel-jest": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@jest/transform": "30.4.1", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.4.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" }, "engines": { - "node": ">=6.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/axios/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/axios/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/babel-jest": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", - "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "30.4.1", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.4.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, "node_modules/babel-plugin-istanbul": { @@ -5794,11 +5474,14 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -5830,9 +5513,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.40", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz", - "integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==", + "version": "2.11.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz", + "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5854,6 +5537,12 @@ "node": ">= 0.8" } }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/bcrypt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", @@ -5878,9 +5567,9 @@ } }, "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", "license": "MIT", "engines": { "node": "*" @@ -5910,30 +5599,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/body-parser": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", @@ -5971,93 +5636,17 @@ "url": "https://opencollective.com/express" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/body-parser/node_modules/media-typer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", - "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/body-parser/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/body-parser/node_modules/type-is": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", - "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", - "license": "MIT", - "dependencies": { - "content-type": "^2.0.0", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/braces": { @@ -6074,9 +5663,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", - "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -6094,10 +5683,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.38", - "caniuse-lite": "^1.0.30001799", - "electron-to-chromium": "^1.5.376", - "node-releases": "^2.0.48", + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -6131,9 +5720,9 @@ } }, "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -6151,7 +5740,7 @@ "license": "MIT", "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "ieee754": "^1.1.13" } }, "node_modules/buffer-equal-constant-time": { @@ -6245,9 +5834,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001800", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001800.tgz", - "integrity": "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==", + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", "dev": true, "funding": [ { @@ -6365,6 +5954,12 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -6405,29 +6000,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clear-module/node_modules/parent-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", - "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clear-module/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": { - "node": ">=8" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -6452,6 +6024,43 @@ "node": ">=12" } }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6768,12 +6377,16 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cookie-parser": { @@ -6812,9 +6425,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -6822,6 +6435,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -7010,19 +6627,6 @@ "node": ">=20" } }, - "node_modules/cspell-glob/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/cspell-grammar": { "version": "9.8.0", "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.8.0.tgz", @@ -7106,16 +6710,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cspell-lib/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": { - "node": ">=8" - } - }, "node_modules/cspell-trie-lib": { "version": "9.8.0", "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.8.0.tgz", @@ -7129,19 +6723,6 @@ "@cspell/cspell-types": "9.8.0" } }, - "node_modules/cspell/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, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/cspell/node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", @@ -7156,12 +6737,20 @@ } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/dedent": { @@ -7271,42 +6860,6 @@ "node": ">=22.12.0" } }, - "node_modules/dependency-cruiser/node_modules/ignore": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", - "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/dependency-cruiser/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/dependency-cruiser/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/des.js": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", @@ -7371,29 +6924,6 @@ "node": ">= 8.0" } }, - "node_modules/docker-modem/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/docker-modem/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/dockerode": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz", @@ -7493,9 +7023,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.383", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.383.tgz", - "integrity": "sha512-I2484/KkAvl8lm9VyjH2JnbOIV0d/UCqT7gbzs6l+o6Vmn9wgB66uVcKX+Vk6HrXtY6fbWTOEXuv8waDTuFNCw==", + "version": "1.5.402", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz", + "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==", "dev": true, "license": "ISC" }, @@ -7513,9 +7043,10 @@ } }, "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==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, "license": "MIT" }, "node_modules/encodeurl": { @@ -7616,14 +7147,15 @@ } }, "node_modules/es-toolkit": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.49.0.tgz", - "integrity": "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", + "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==", "dev": true, "license": "MIT", "workspaces": [ "docs", - "benchmarks" + "benchmarks", + "tests/types" ] }, "node_modules/es6-promise": { @@ -7754,9 +7286,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.15.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.4.tgz", - "integrity": "sha512-6ln5i9Nkrb27X4w91ZPt/xHDsVQnvxTS2ntgq6r32u+8gymdUrp88TdcBXSveZW0Dl+M5v2H6K75kJhMvUGhjg==", + "version": "29.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.0.tgz", + "integrity": "sha512-0WFBxDHlT2ratGQfnFQEVIsgQJ5cfd+0IV8Kc6U3X2onB8ATLG23voD2Ch5G9fCkEpCPmCMuzW0tbS0kYb8biw==", "dev": true, "license": "MIT", "dependencies": { @@ -7769,7 +7301,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", - "typescript": ">=4.8.4 <7.0.0" + "typescript": ">=4.8.4 <8.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -7804,6 +7336,13 @@ "eslint": ">=5.16.0" } }, + "node_modules/eslint-plugin-node/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-node/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -7815,6 +7354,16 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint-plugin-node/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": { + "node": ">= 4" + } + }, "node_modules/eslint-plugin-node/node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -7942,6 +7491,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -7953,22 +7509,14 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/eslint/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", - "dependencies": { - "ms": "^2.1.3" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 4" } }, "node_modules/eslint/node_modules/json-schema-traverse": { @@ -7991,13 +7539,6 @@ "node": "*" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -8031,9 +7572,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -8112,32 +7653,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/exit-x": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", @@ -8210,9 +7725,9 @@ } }, "node_modules/express/node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8227,98 +7742,6 @@ "node": ">=6.6.0" } }, - "node_modules/express/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/express/node_modules/media-typer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", - "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/express/node_modules/type-is": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", - "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", - "license": "MIT", - "dependencies": { - "content-type": "^2.0.0", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/type-is/node_modules/content-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", - "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -8340,49 +7763,19 @@ "license": "Apache-2.0" }, "node_modules/fast-equals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.0.tgz", - "integrity": "sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.2.tgz", + "integrity": "sha512-sAjhj9ZhOxYCGiNMnZLaucOqf5ZeFnHNoKoAZiD9thhJ0N8RP85qJK759/97C/3L7NzzmGVB5uiX9AUpySZmUQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", + "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" }, @@ -8445,9 +7838,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { @@ -8474,6 +7867,24 @@ "walk-up-path": "^4.0.0" } }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/figures": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", @@ -8537,29 +7948,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", @@ -8605,9 +7993,9 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, @@ -8648,19 +8036,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", @@ -8677,6 +8052,27 @@ "node": ">= 6" } }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/formatly": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/formatly/-/formatly-0.3.0.tgz", @@ -8797,13 +8193,48 @@ "node": ">=14" } }, + "node_modules/gaxios/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/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==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", "license": "Apache-2.0", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" }, "engines": { @@ -8903,23 +8334,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stream/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-tsconfig": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", - "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.1.tgz", + "integrity": "sha512-Dz/6HxkrxgNehhxLVeyv8sad9UzF2xBVeaKBQNDfJ5XiSXmp2gTR0eO0RWiT2NCKS5aGP9jjkOMggTN90qU50A==", "dev": true, "license": "MIT", "dependencies": { @@ -8948,22 +8366,22 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "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": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8982,28 +8400,37 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.2" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/global-directory": { @@ -9039,9 +8466,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.14.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.1.tgz", - "integrity": "sha512-Rj+PMjoNFGFTmtItH7gHfbHpGVSb3vmnGK3nwNBqxQF9NoBpttSZI/rc0WiM63ma2uGDQtYEkMHkK9U6937NiA==", + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -9055,6 +8482,15 @@ "node": ">=14" } }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -9116,6 +8552,16 @@ "uglify-js": "^3.1.4" } }, + "node_modules/handlebars/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": { + "node": ">=0.10.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9165,9 +8611,9 @@ } }, "node_modules/helmet": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", - "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.2.0.tgz", + "integrity": "sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==", "license": "MIT", "engines": { "node": ">=16.0.0" @@ -9201,41 +8647,18 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 6" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/human-signals": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", @@ -9299,9 +8722,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -9332,6 +8755,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/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": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=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": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -9450,13 +8896,13 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -9626,12 +9072,13 @@ } }, "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==", - "license": "MIT", - "engines": { - "node": ">=8" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9699,22 +9146,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", @@ -9730,42 +9161,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", @@ -9885,6 +9280,19 @@ "node": ">=10.17.0" } }, + "node_modules/jest-changed-files/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": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-changed-files/node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -9898,6 +9306,13 @@ "node": ">=8" } }, + "node_modules/jest-changed-files/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/jest-changed-files/node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -10024,38 +9439,6 @@ } } }, - "node_modules/jest-config/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "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": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-config/node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/jest-diff": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", @@ -10146,19 +9529,6 @@ "fsevents": "^2.3.3" } }, - "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-leak-detector": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", @@ -10211,19 +9581,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-message-util/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-mock": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", @@ -10385,48 +9742,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "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": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-runtime/node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/jest-runtime/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": { - "node": ">=8" - } - }, "node_modules/jest-snapshot": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", @@ -10478,19 +9793,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/jest-validate": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", @@ -10702,9 +10004,9 @@ } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -10756,9 +10058,9 @@ } }, "node_modules/knip": { - "version": "6.24.0", - "resolved": "https://registry.npmjs.org/knip/-/knip-6.24.0.tgz", - "integrity": "sha512-PokLlgeEjLh1rAsB7ts+52wZ37HBr1nDhE6NNONwEaXdeZGCJOkP7ZlIAI2Gtu8xohquzTWy75bc/1diI9shQw==", + "version": "6.32.0", + "resolved": "https://registry.npmjs.org/knip/-/knip-6.32.0.tgz", + "integrity": "sha512-KDX9OmmOFmlvmxTkrx6Z0GHISMut+pXMSKR8eg84bovaxJKx2NdQD4JYCXveSbvieRe107W6vCD2xCpmz0qBYA==", "dev": true, "funding": [ { @@ -10774,17 +10076,17 @@ "dependencies": { "fdir": "^6.5.0", "formatly": "^0.3.0", - "get-tsconfig": "4.14.0", + "get-tsconfig": "4.14.1", "jiti": "^2.7.0", - "oxc-parser": "^0.137.0", - "oxc-resolver": "11.21.3", - "picomatch": "^4.0.4", - "smol-toml": "^1.6.1", + "oxc-parser": "^0.142.0", + "oxc-resolver": "11.24.2", + "picomatch": "^4.0.5", + "smol-toml": "^1.7.1", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.17", - "unbash": "^4.0.1", + "unbash": "^4.0.4", "yaml": "^2.9.0", - "zod": "^4.1.11" + "zod": "^4.4.3" }, "bin": { "knip": "bin/knip.js", @@ -10794,24 +10096,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/knip/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/knip/node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -10822,19 +10106,6 @@ "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/knip/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/knip/node_modules/strip-json-comments": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", @@ -10903,19 +10174,6 @@ "yaml": "^2.9.0" } }, - "node_modules/lint-staged/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -10989,12 +10247,21 @@ "yallist": "^3.0.2" } }, - "node_modules/lru-cache/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/make-error": { "version": "1.3.6", @@ -11023,12 +10290,16 @@ } }, "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/meow": { @@ -11063,59 +10334,52 @@ "dev": true, "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "bin": { + "mime": "cli.js" }, "engines": { - "node": ">=8.6" + "node": ">=4.0.0" } }, "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/mimic-fn": { @@ -11136,16 +10400,16 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11162,13 +10426,13 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/mkdirp-classic": { @@ -11178,9 +10442,9 @@ "license": "MIT" }, "node_modules/module-alias": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", - "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.3.4.tgz", + "integrity": "sha512-bOclZt8hkpuGgSSoG07PKmvzTizROilUTvLNyrMqvlC9snhs7y7GzjNWAVbISIOlhCP1T14rH1PDAV9iNyBq/w==", "license": "MIT" }, "node_modules/moment": { @@ -11193,9 +10457,9 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", "license": "MIT", "dependencies": { "moment": "^2.29.4" @@ -11224,12 +10488,27 @@ "url": "https://opencollective.com/express" } }, - "node_modules/ms": { + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/multer": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/multer/-/multer-2.2.0.tgz", @@ -11249,6 +10528,49 @@ "url": "https://opencollective.com/express" } }, + "node_modules/multer/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mutation-server-protocol": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/mutation-server-protocol/-/mutation-server-protocol-0.4.1.tgz", @@ -11343,9 +10665,9 @@ "license": "MIT" }, "node_modules/node-addon-api": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.0.tgz", - "integrity": "sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==", + "version": "8.9.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.1.tgz", + "integrity": "sha512-4eUQWVPCUUUiBjLnHS3cXWeC6ryoPUc0U3rP7IuzapoGbzMqd/r6KKO0clr0b+snQhsrueFEhCZDdK+LK7hxKg==", "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" @@ -11415,10 +10737,34 @@ "uuid": "^9.0.0" } }, + "node_modules/node-jose/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/node-releases": { - "version": "2.0.50", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", - "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "dev": true, "license": "MIT", "engines": { @@ -11426,9 +10772,9 @@ } }, "node_modules/nodemailer": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.3.tgz", - "integrity": "sha512-n+YP+NKwR5zRWa60k3GiQ6Q3B4KXCoAw40dAKeCtYn020iNN74aWK2liXIC3ZEATeGql7we3tE3t8QwhY0eskw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.5.tgz", + "integrity": "sha512-wvjiKvjczmsN7U/8006JOdXubgBk2XFAbioDMbT+sM7cPs0QrhJTa6KBRX7P5REGGkDcLUz/EarWidb8G8C1jQ==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -11463,47 +10809,6 @@ "url": "https://opencollective.com/nodemon" } }, - "node_modules/nodemon/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/nodemon/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/nodemon/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -11514,29 +10819,6 @@ "node": ">=4" } }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.8" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/nodemon/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11676,13 +10958,13 @@ } }, "node_modules/oxc-parser": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.137.0.tgz", - "integrity": "sha512-yFImD+WLElJpLKy8llG1qe4DCmMsL18peRp8XP1JKfig/gISbJkglnpDtX2aTmAn10kZF7164HbN2H8QPsXxGg==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.142.0.tgz", + "integrity": "sha512-kKR+jPiRJYJDexVoziIg/FVGvr1fT1FZSSJOk6tVoMKKSlsf1Cso+cgGCJkOEDWOP174vRntCPFKg+AS7InWvw==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "^0.137.0" + "@oxc-project/types": "^0.142.0" }, "engines": { "node": "^20.19.0 || >=22.12.0" @@ -11691,57 +10973,57 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxc-parser/binding-android-arm-eabi": "0.137.0", - "@oxc-parser/binding-android-arm64": "0.137.0", - "@oxc-parser/binding-darwin-arm64": "0.137.0", - "@oxc-parser/binding-darwin-x64": "0.137.0", - "@oxc-parser/binding-freebsd-x64": "0.137.0", - "@oxc-parser/binding-linux-arm-gnueabihf": "0.137.0", - "@oxc-parser/binding-linux-arm-musleabihf": "0.137.0", - "@oxc-parser/binding-linux-arm64-gnu": "0.137.0", - "@oxc-parser/binding-linux-arm64-musl": "0.137.0", - "@oxc-parser/binding-linux-ppc64-gnu": "0.137.0", - "@oxc-parser/binding-linux-riscv64-gnu": "0.137.0", - "@oxc-parser/binding-linux-riscv64-musl": "0.137.0", - "@oxc-parser/binding-linux-s390x-gnu": "0.137.0", - "@oxc-parser/binding-linux-x64-gnu": "0.137.0", - "@oxc-parser/binding-linux-x64-musl": "0.137.0", - "@oxc-parser/binding-openharmony-arm64": "0.137.0", - "@oxc-parser/binding-wasm32-wasi": "0.137.0", - "@oxc-parser/binding-win32-arm64-msvc": "0.137.0", - "@oxc-parser/binding-win32-ia32-msvc": "0.137.0", - "@oxc-parser/binding-win32-x64-msvc": "0.137.0" + "@oxc-parser/binding-android-arm-eabi": "0.142.0", + "@oxc-parser/binding-android-arm64": "0.142.0", + "@oxc-parser/binding-darwin-arm64": "0.142.0", + "@oxc-parser/binding-darwin-x64": "0.142.0", + "@oxc-parser/binding-freebsd-x64": "0.142.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.142.0", + "@oxc-parser/binding-linux-arm-musleabihf": "0.142.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.142.0", + "@oxc-parser/binding-linux-arm64-musl": "0.142.0", + "@oxc-parser/binding-linux-ppc64-gnu": "0.142.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.142.0", + "@oxc-parser/binding-linux-riscv64-musl": "0.142.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.142.0", + "@oxc-parser/binding-linux-x64-gnu": "0.142.0", + "@oxc-parser/binding-linux-x64-musl": "0.142.0", + "@oxc-parser/binding-openharmony-arm64": "0.142.0", + "@oxc-parser/binding-wasm32-wasi": "0.142.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.142.0", + "@oxc-parser/binding-win32-ia32-msvc": "0.142.0", + "@oxc-parser/binding-win32-x64-msvc": "0.142.0" } }, "node_modules/oxc-resolver": { - "version": "11.21.3", - "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.21.3.tgz", - "integrity": "sha512-2Mx3fKQz7+xgrBONjsxOgCGtMHOn38/HxMzW1I5efwXB5a4lRN0Vp40gYUJFBWJslcrvwoofTrqoTnLbwTd3pA==", + "version": "11.24.2", + "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.24.2.tgz", + "integrity": "sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxc-resolver/binding-android-arm-eabi": "11.21.3", - "@oxc-resolver/binding-android-arm64": "11.21.3", - "@oxc-resolver/binding-darwin-arm64": "11.21.3", - "@oxc-resolver/binding-darwin-x64": "11.21.3", - "@oxc-resolver/binding-freebsd-x64": "11.21.3", - "@oxc-resolver/binding-linux-arm-gnueabihf": "11.21.3", - "@oxc-resolver/binding-linux-arm-musleabihf": "11.21.3", - "@oxc-resolver/binding-linux-arm64-gnu": "11.21.3", - "@oxc-resolver/binding-linux-arm64-musl": "11.21.3", - "@oxc-resolver/binding-linux-ppc64-gnu": "11.21.3", - "@oxc-resolver/binding-linux-riscv64-gnu": "11.21.3", - "@oxc-resolver/binding-linux-riscv64-musl": "11.21.3", - "@oxc-resolver/binding-linux-s390x-gnu": "11.21.3", - "@oxc-resolver/binding-linux-x64-gnu": "11.21.3", - "@oxc-resolver/binding-linux-x64-musl": "11.21.3", - "@oxc-resolver/binding-openharmony-arm64": "11.21.3", - "@oxc-resolver/binding-wasm32-wasi": "11.21.3", - "@oxc-resolver/binding-win32-arm64-msvc": "11.21.3", - "@oxc-resolver/binding-win32-x64-msvc": "11.21.3" + "@oxc-resolver/binding-android-arm-eabi": "11.24.2", + "@oxc-resolver/binding-android-arm64": "11.24.2", + "@oxc-resolver/binding-darwin-arm64": "11.24.2", + "@oxc-resolver/binding-darwin-x64": "11.24.2", + "@oxc-resolver/binding-freebsd-x64": "11.24.2", + "@oxc-resolver/binding-linux-arm-gnueabihf": "11.24.2", + "@oxc-resolver/binding-linux-arm-musleabihf": "11.24.2", + "@oxc-resolver/binding-linux-arm64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-arm64-musl": "11.24.2", + "@oxc-resolver/binding-linux-ppc64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-riscv64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-riscv64-musl": "11.24.2", + "@oxc-resolver/binding-linux-s390x-gnu": "11.24.2", + "@oxc-resolver/binding-linux-x64-gnu": "11.24.2", + "@oxc-resolver/binding-linux-x64-musl": "11.24.2", + "@oxc-resolver/binding-openharmony-arm64": "11.24.2", + "@oxc-resolver/binding-wasm32-wasi": "11.24.2", + "@oxc-resolver/binding-win32-arm64-msvc": "11.24.2", + "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" } }, "node_modules/p-limit": { @@ -11794,22 +11076,32 @@ "license": "BlueOak-1.0.0" }, "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.2.0.tgz", + "integrity": "sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "(MIT AND Zlib)" }, "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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", + "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", "dev": true, "license": "MIT", "dependencies": { - "callsites": "^3.0.0" + "callsites": "^3.1.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/parse-json": { @@ -12021,13 +11313,13 @@ "license": "ISC" }, "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==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -12122,9 +11414,9 @@ } }, "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12432,9 +11724,9 @@ }, "node_modules/react-is-19": { "name": "react-is", - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", - "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", + "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", "dev": true, "license": "MIT" }, @@ -12465,6 +11757,19 @@ "node": ">=8.10.0" } }, + "node_modules/readdirp/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": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -12530,19 +11835,23 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12560,7 +11869,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "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==", @@ -12570,16 +11879,6 @@ "node": ">=8" } }, - "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": { - "node": ">=4" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -12591,15 +11890,15 @@ } }, "node_modules/retry-as-promised": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", - "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.1.1.tgz", + "integrity": "sha512-hMD7odLOt3LkTjcif8aRZqi/hybjpLNgSk5oF5FCowfCjok6LukpN2bDX7R5wDmbgBQFn7YoBxSagmtXHaJYJw==", "license": "MIT" }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -12624,7 +11923,60 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/router": { + "node_modules/rimraf/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/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": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/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": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", @@ -12640,29 +11992,6 @@ "node": ">= 18" } }, - "node_modules/router/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/router/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12698,9 +12027,23 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, "node_modules/safe-regex": { @@ -12720,9 +12063,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12757,54 +12100,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/send/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/send/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/send/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/sequelize": { "version": "6.37.8", "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.8.tgz", @@ -12876,29 +12171,6 @@ "node": ">= 10.0.0" } }, - "node_modules/sequelize/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/sequelize/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", @@ -13020,11 +12292,17 @@ } }, "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/simple-update-notifier": { "version": "2.0.0", @@ -13057,9 +12335,9 @@ } }, "node_modules/smol-toml": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.0.tgz", - "integrity": "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz", + "integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -13070,13 +12348,13 @@ } }, "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==", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, "license": "BSD-3-Clause", "engines": { - "node": ">=0.10.0" + "node": ">= 12" } }, "node_modules/source-map-support": { @@ -13090,6 +12368,16 @@ "source-map": "^0.6.0" } }, + "node_modules/source-map-support/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": { + "node": ">=0.10.0" + } + }, "node_modules/split-ca": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", @@ -13178,26 +12466,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/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", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -13229,17 +12497,21 @@ } }, "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==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -13258,6 +12530,36 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/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/string-width/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -13284,14 +12586,33 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/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": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "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": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-final-newline": { @@ -13318,67 +12639,29 @@ }, "funding": { "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/superagent": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", - "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "component-emitter": "^1.3.1", - "cookiejar": "^2.1.4", - "debug": "^4.3.7", - "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.5", - "formidable": "^3.5.4", - "methods": "^1.1.2", - "mime": "2.6.0", - "qs": "^6.14.1" - }, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/superagent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/superagent/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + } + }, + "node_modules/superagent": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", + "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", "dev": true, "license": "MIT", - "bin": { - "mime": "cli.js" + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.5", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.14.1" }, "engines": { - "node": ">=4.0.0" + "node": ">=14.18.0" } }, - "node_modules/superagent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/supertest": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz", @@ -13504,12 +12787,6 @@ "tar-stream": "^2.1.4" } }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -13541,6 +12818,13 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/test-exclude/node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -13552,6 +12836,28 @@ "concat-map": "0.0.1" } }, + "node_modules/test-exclude/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": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -13573,9 +12879,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", - "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", "dev": true, "license": "MIT", "engines": { @@ -13599,37 +12905,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -13692,16 +12967,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-command-line-args": { @@ -13735,9 +13010,9 @@ } }, "node_modules/ts-jest": { - "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", "dev": true, "license": "MIT", "dependencies": { @@ -13747,7 +13022,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.8.0", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -13787,19 +13062,6 @@ } } }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ts-jest/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", @@ -13888,6 +13150,16 @@ "node": ">=10.13.0" } }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -13948,16 +13220,34 @@ } }, "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/typed-inject": { @@ -13994,9 +13284,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -14031,9 +13321,9 @@ } }, "node_modules/unbash": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unbash/-/unbash-4.0.2.tgz", - "integrity": "sha512-8gwNZ29+0/3zmXw7ToIHZtg6wK37xnniRUdBt7B27xZxaxfgR5tGMaGHT0t0dLtBV9fXE7zurh0s6Z1DHVjfWg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/unbash/-/unbash-4.0.7.tgz", + "integrity": "sha512-P3NODenm+qh2PwrP3gzJBx7a541oRtrUTRCyMH8K53P27oZjstMwf7A3CqwWtLLLOIUigRqjdEHSn2UHBQlASA==", "dev": true, "license": "ISC", "engines": { @@ -14055,9 +13345,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/unicorn-magic": { @@ -14131,9 +13421,9 @@ } }, "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==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", + "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", "dev": true, "funding": [ { @@ -14212,17 +13502,6 @@ "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/validator": { "version": "13.15.35", "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", @@ -14376,17 +13655,18 @@ } }, "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==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -14411,6 +13691,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -14431,23 +13762,10 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ws": { - "version": "8.21.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", - "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -14496,6 +13814,13 @@ "node": ">=10" } }, + "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/yaml": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", @@ -14539,6 +13864,26 @@ "node": ">=12" } }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -14563,9 +13908,9 @@ } }, "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", "dev": true, "license": "MIT", "engines": { From b5b94b3bee24891c13e09ef32478711cd9ad07da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Bou=C3=A9?= Date: Fri, 7 Aug 2026 19:19:02 +0200 Subject: [PATCH 2/3] chore: migrate backend to Node 24 ESM, Vitest, and Biome --- ...ency-cruiser.js => .dependency-cruiser.cjs | 0 .eslintignore | 1 - .lintstagedrc.json | 11 +- biome.json | 38 + build.ts | 2 +- commitlint.config.js => commitlint.config.cjs | 0 eslint.config.mjs | 149 + jest.config.ts | 51 - jest.setup.ts | 27 - package-lock.json | 8929 +++++++---------- package.json | 87 +- src/CompositionRoot.ts | 108 +- src/DataProviders/BaseRepository.ts | 14 +- src/DataProviders/Bug/Bug.ts | 2 +- src/DataProviders/Bug/BugAssociations.ts | 10 +- src/DataProviders/Bug/BugAttachment.ts | 2 +- src/DataProviders/Bug/BugLog.ts | 7 +- src/DataProviders/Bug/BugNote.ts | 9 +- src/DataProviders/Bug/BugRepository.ts | 197 +- .../Countries/CountriesRepository.ts | 50 +- src/DataProviders/Countries/Country.ts | 7 +- .../Metrics/MetricsRepository.ts | 93 +- .../MicroService/MicroServiceRepository.ts | 93 +- src/DataProviders/Permission/Permission.ts | 7 +- .../Permission/PermissionRepository.ts | 93 +- src/DataProviders/Role/Role.ts | 2 +- src/DataProviders/Role/RolePermission.ts | 6 +- .../Role/RolePermissionRepository.ts | 40 +- src/DataProviders/Role/RoleRepository.ts | 104 +- src/DataProviders/User/User.ts | 4 +- src/DataProviders/User/UserRepository.ts | 290 +- src/DataProviders/User/UserRole.ts | 11 +- src/DataProviders/User/UserRoleRepository.ts | 84 +- src/DataProviders/Visit/Visit.ts | 7 +- src/DataProviders/Visit/VisitRepository.ts | 33 +- src/Domain/Bug/Entity/Bug.spec.ts | 18 +- src/Domain/Bug/Entity/Bug.ts | 9 +- src/Domain/Bug/Entity/BugNote.test.ts | 2 +- src/Domain/Bug/Entity/BugPriority.spec.ts | 2 +- src/Domain/Bug/Entity/BugPriority.ts | 4 +- src/Domain/Bug/Entity/BugStatusLog.test.ts | 2 +- src/Domain/Bug/Repository/IBugRepository.ts | 30 +- src/Domain/Bug/Repository/IUserRepository.ts | 8 +- .../Bug/Service/GitHubTokenResolver.test.ts | 91 +- src/Domain/Bug/Service/GitHubTokenResolver.ts | 22 +- .../Bug/UseCase/BugAttachmentUseCase.test.ts | 67 +- .../Bug/UseCase/BugAttachmentUseCase.ts | 33 +- .../Bug/UseCase/BugLifecycleUseCase.test.ts | 179 +- src/Domain/Bug/UseCase/BugLifecycleUseCase.ts | 111 +- .../Bug/UseCase/BugQueryUseCase.test.ts | 38 +- src/Domain/Bug/UseCase/BugQueryUseCase.ts | 46 +- .../Bug/UseCase/BugSubmissionUseCase.test.ts | 70 +- .../Bug/UseCase/BugSubmissionUseCase.ts | 39 +- src/Domain/Bug/UseCase/BugSyncUseCase.test.ts | 175 +- src/Domain/Bug/UseCase/BugSyncUseCase.ts | 38 +- src/Domain/Core/Entity/PagedModel.ts | 2 +- src/Domain/Core/Entity/ResponseModel.spec.ts | 4 +- src/Domain/Core/Entity/ResponseModel.ts | 14 +- .../Core/Service/IIssueTrackerService.ts | 12 +- src/Domain/Countries/Entity/Country.ts | 15 +- .../Repository/ICountriesRepository.ts | 14 +- .../UseCase/CountriesQueryUseCase.test.ts | 26 +- .../UseCase/CountriesQueryUseCase.ts | 16 +- src/Domain/Menu/Entity/Menu.ts | 6 +- src/Domain/Metrics/Entity/Metric.test.ts | 12 +- .../Metrics/Entity/MetricsFilter.test.ts | 2 +- src/Domain/Metrics/Entity/MetricsFilter.ts | 6 +- .../Metrics/Repository/IMetricsRepository.ts | 12 +- .../UseCase/MetricsQueryUseCase.test.ts | 34 +- .../Metrics/UseCase/MetricsQueryUseCase.ts | 28 +- .../MicroService/Entity/MicroService.test.ts | 53 +- .../MicroService/Entity/MicroService.ts | 10 +- .../MicroService/Entity/MicroServiceFilter.ts | 10 +- .../Repository/IMicroServiceRepository.ts | 20 +- .../MicroServiceManagementUseCase.test.ts | 97 +- .../UseCase/MicroServiceManagementUseCase.ts | 33 +- .../UseCase/MicroServiceQueryUseCase.test.ts | 44 +- .../UseCase/MicroServiceQueryUseCase.ts | 20 +- .../Permission/Entity/Permission.test.ts | 7 +- src/Domain/Permission/Entity/Permission.ts | 5 +- .../Permission/Entity/PermissionFilter.ts | 11 +- .../Repository/IPermissionRepository.ts | 20 +- .../UseCase/PermissionUseCase.test.ts | 30 +- .../Permission/UseCase/PermissionUseCase.ts | 30 +- src/Domain/Role/Entity/Role.test.ts | 2 +- src/Domain/Role/Entity/Role.ts | 13 +- src/Domain/Role/Entity/RoleFilter.ts | 11 +- src/Domain/Role/Entity/RolePermission.ts | 2 +- .../Role/Entity/RolePermissionFilter.ts | 12 +- src/Domain/Role/IRoleRepository.ts | 6 +- .../Role/Repository/IGuestRoleRepository.ts | 6 +- .../Repository/IRolePermissionRepository.ts | 14 +- src/Domain/Role/Repository/IRoleRepository.ts | 8 +- .../UseCase/RoleManagementUseCase.test.ts | 16 +- .../Role/UseCase/RoleManagementUseCase.ts | 12 +- .../UseCase/RolePermissionUseCase.test.ts | 48 +- .../Role/UseCase/RolePermissionUseCase.ts | 20 +- .../Role/UseCase/RoleQueryUseCase.test.ts | 18 +- src/Domain/Role/UseCase/RoleQueryUseCase.ts | 18 +- src/Domain/User/Entity/Email.test.ts | 2 +- src/Domain/User/Entity/Password.test.ts | 6 +- src/Domain/User/Entity/PasswordUpdate.ts | 4 +- .../Entity/PersonalInformationUpdate.test.ts | 6 +- .../User/Entity/PersonalInformationUpdate.ts | 15 +- src/Domain/User/Entity/SessionInfoResponse.ts | 2 +- src/Domain/User/Entity/User.test.ts | 2 +- src/Domain/User/Entity/User.ts | 4 +- src/Domain/User/Entity/UserFilter.test.ts | 12 +- src/Domain/User/Entity/UserFilter.ts | 4 +- src/Domain/User/Entity/UserRegistration.ts | 24 +- src/Domain/User/Entity/UserRole.ts | 2 +- src/Domain/User/Entity/UserRoleFilter.ts | 8 +- src/Domain/User/IUserRepository.ts | 26 +- .../User/Repository/IUserRoleRepository.ts | 22 +- .../Service/PasswordResetTokenService.test.ts | 46 +- .../User/Service/PasswordResetTokenService.ts | 22 +- .../User/UseCase/UserAuthUseCase.test.ts | 48 +- src/Domain/User/UseCase/UserAuthUseCase.ts | 41 +- .../UseCase/UserManagementUseCase.test.ts | 54 +- .../User/UseCase/UserManagementUseCase.ts | 35 +- .../User/UseCase/UserPasswordUseCase.test.ts | 158 +- .../User/UseCase/UserPasswordUseCase.ts | 102 +- .../User/UseCase/UserQueryUseCase.test.ts | 26 +- src/Domain/User/UseCase/UserQueryUseCase.ts | 26 +- .../User/UseCase/UserRoleUseCase.test.ts | 20 +- src/Domain/User/UseCase/UserRoleUseCase.ts | 24 +- .../Validations/ValidationConstants.test.ts | 4 +- src/Domain/Validations/ValidationConstants.ts | 4 +- src/Domain/Visit/Entity/Visit.ts | 8 +- .../Visit/Repository/IVisitRepository.ts | 6 +- src/Domain/Visit/UseCase/VisitUseCase.test.ts | 100 +- src/Domain/Visit/UseCase/VisitUseCase.ts | 19 +- src/EntryPoints/AuthRouter.test.ts | 1022 +- src/EntryPoints/AuthRouter.ts | 311 +- src/EntryPoints/BugRouter.spec.ts | 210 +- src/EntryPoints/BugRouter.ts | 335 +- src/EntryPoints/ConfigurationRouter.test.ts | 6 +- src/EntryPoints/ConfigurationRouter.ts | 26 +- src/EntryPoints/CountriesV1Router.test.ts | 56 +- src/EntryPoints/CountriesV1Router.ts | 16 +- src/EntryPoints/MetricsV1Router.test.ts | 67 +- src/EntryPoints/MetricsV1Router.ts | 58 +- src/EntryPoints/MicroServicesV1Router.test.ts | 271 +- src/EntryPoints/MicroServicesV1Router.ts | 96 +- src/EntryPoints/PermissionsV1Router.test.ts | 204 +- src/EntryPoints/PermissionsV1Router.ts | 173 +- .../RolePermissionsV1Router.test.ts | 160 +- src/EntryPoints/RolePermissionsV1Router.ts | 46 +- src/EntryPoints/RolesV1Router.test.ts | 185 +- src/EntryPoints/RolesV1Router.ts | 112 +- src/EntryPoints/UserRolesV1Router.test.ts | 150 +- src/EntryPoints/UserRolesV1Router.ts | 44 +- src/EntryPoints/UsersV1Router.test.ts | 167 +- src/EntryPoints/UsersV1Router.ts | 55 +- src/EntryPoints/VisitsV1Router.test.ts | 64 +- src/EntryPoints/VisitsV1Router.ts | 17 +- src/EntryPoints/errorMapper.test.ts | 18 +- src/EntryPoints/errorMapper.ts | 6 +- src/EntryPoints/index.ts | 86 +- .../GitHub/GitHubIssuesService.ts | 34 +- src/Infrastructure/Mail/MailService.ts | 29 +- .../Storage/DiskStorageService.ts | 10 +- src/Infrastructure/VariamosORM.ts | 39 +- src/common/HttpStatusCodes.ts | 2 +- src/common/classes.ts | 4 +- src/index.ts | 86 +- src/pre-start.ts | 2 +- src/server.ts | 23 +- stryker.config.json | 11 +- stryker.domain.config.json | 11 +- stryker.entrypoints.config.json | 11 +- tsconfig.json | 4 +- vitest.config.ts | 33 + vitest.setup.ts | 31 + 174 files changed, 9229 insertions(+), 8295 deletions(-) rename .dependency-cruiser.js => .dependency-cruiser.cjs (100%) delete mode 100644 .eslintignore create mode 100644 biome.json rename commitlint.config.js => commitlint.config.cjs (100%) create mode 100644 eslint.config.mjs delete mode 100644 jest.config.ts delete mode 100644 jest.setup.ts create mode 100644 vitest.config.ts create mode 100644 vitest.setup.ts diff --git a/.dependency-cruiser.js b/.dependency-cruiser.cjs similarity index 100% rename from .dependency-cruiser.js rename to .dependency-cruiser.cjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 42e42be..0000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -src/public/ diff --git a/.lintstagedrc.json b/.lintstagedrc.json index bf1e9c4..55661db 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,11 +1,14 @@ { "src/**/*.ts": [ - "prettier --write", - "eslint --fix", + "biome check --write", "cspell" ], - "src/**/*.{js,json,md}": [ - "prettier --write", + "src/**/*.{js,json}": [ + "biome check --write", + "cspell" + ], + "src/**/*.md": [ + "biome format --write", "cspell" ] } diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..808b390 --- /dev/null +++ b/biome.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignore": ["dist/**", "coverage/**", ".stryker-tmp/**", "node_modules/**"] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 80 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "error" + }, + "correctness": { + "noUnusedVariables": "warn" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always" + } + } +} diff --git a/build.ts b/build.ts index aa432b5..895b809 100644 --- a/build.ts +++ b/build.ts @@ -14,7 +14,7 @@ import logger from "jet-logger"; // Remove current build await remove("./dist/"); // Copy back-end files - await exec("tsc --build tsconfig.prod.json", "./"); + await exec("tsc --build tsconfig.prod.json && npx tsc-alias -p tsconfig.prod.json", "./"); } catch (err) { logger.err(err); process.exit(1); diff --git a/commitlint.config.js b/commitlint.config.cjs similarity index 100% rename from commitlint.config.js rename to commitlint.config.cjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..5a537db --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,149 @@ +import eslint from '@eslint/js'; +import tsParser from '@typescript-eslint/parser'; +import tsPlugin from '@typescript-eslint/eslint-plugin'; +import nodePlugin from 'eslint-plugin-n'; +import prettierPlugin from 'eslint-plugin-prettier'; +import jestPlugin from 'eslint-plugin-jest'; +import globals from 'globals'; + +export default [ + // Global ignores (replaces .eslintignore) + { + ignores: ['dist/**', 'coverage/**', 'node_modules/**', '.stryker-tmp/**'], + }, + // Base configuration + { + files: ['**/*.ts', '**/*.js'], + languageOptions: { + parser: tsParser, + parserOptions: { + project: './tsconfig.json', + }, + globals: { + ...globals.node, + }, + }, + plugins: { + '@typescript-eslint': tsPlugin, + 'n': nodePlugin, + 'node': nodePlugin, + 'prettier': prettierPlugin, + }, + settings: { + node: { + tryExtensions: ['.js', '.json', '.node', '.ts'], + }, + }, + rules: { + // Base ESLint recommended rules + ...eslint.configs.recommended.rules, + + // TypeScript eslint recommended overrides + ...tsPlugin.configs.recommended.rules, + ...tsPlugin.configs['recommended-requiring-type-checking']?.rules, + + // Node plugin recommended overrides + ...nodePlugin.configs.recommended.rules, + + // Custom Rules + '@typescript-eslint/explicit-member-accessibility': 'warn', + '@typescript-eslint/no-misused-promises': 0, + '@typescript-eslint/no-floating-promises': 0, + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-non-null-assertion': 'warn', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', + '@typescript-eslint/no-base-to-string': 'off', + 'no-undef': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_' } + ], + 'no-restricted-syntax': [ + 'error', + { + selector: "TSAsExpression[expression.type='TSAsExpression']", + message: "Double assertions (e.g., 'as unknown as T') are forbidden. Cast directly or use explicit mapping functions." + }, + { + selector: "TSUnknownKeyword", + message: "The 'unknown' type is forbidden. Use concrete types, generics (T), or 'void' for empty values. If you really think you need 'unknown' for a specific exception, disable the linter on that line using '// eslint-disable-next-line no-restricted-syntax'." + } + ], + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['**/../../*'], + message: 'Please use the @src alias instead of deep relative imports (../../).' + } + ] + } + ], + 'no-console': [ + 'error', + { allow: ['warn', 'error'] } + ], + 'no-extra-boolean-cast': 0, + 'node/no-process-env': 1, + 'node/no-unsupported-features/es-syntax': [ + 'error', + { ignores: ['modules'] } + ], + 'node/no-missing-import': 0, + 'node/no-unpublished-import': 0, + 'prettier/prettier': [ + 'error', + { + endOfLine: 'auto' + } + ] + } + }, + // Domain layer specific rules + { + files: ['src/Domain/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@src/DataProviders/**', '@src/EntryPoints/**', '@src/Infrastructure/**'], + message: 'The Domain layer must be pure. Do not import from DataProviders, EntryPoints, or Infrastructure. Use Dependency Injection.' + }, + { + group: ['**/../../*'], + message: 'Please use the @src alias instead of deep relative imports (../../).' + } + ] + } + ] + } + }, + // Test files specific configuration + { + files: ['**/*.spec.ts', '**/*.test.ts'], + plugins: { + jest: jestPlugin, + }, + languageOptions: { + globals: { + ...jestPlugin.environments.globals.globals, + }, + }, + rules: { + ...jestPlugin.configs.recommended.rules, + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-identical-title': 'error', + 'jest/expect-expect': 'error', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/unbound-method': 'off', + 'no-restricted-syntax': 'off' + } + } +]; diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 4431e07..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { Config } from "jest"; -import * as dotenv from "dotenv"; -import * as path from "path"; - -// Load the test environment variables before anything else -dotenv.config({ path: path.join(process.cwd(), "env/test.env") }); - -const config: Config = { - preset: "ts-jest", - testEnvironment: "node", - moduleNameMapper: { - "^@src/(.*)$": "/src/$1", - }, - testMatch: ["**/src/**/*.spec.ts", "**/src/**/*.test.ts"], - testPathIgnorePatterns: ["/node_modules/", "/.stryker-tmp/"], - setupFilesAfterEnv: ["/jest.setup.ts"], - verbose: true, - forceExit: true, - clearMocks: true, - resetMocks: true, - restoreMocks: true, - collectCoverageFrom: [ - "src/Domain/**/*.ts", - "src/EntryPoints/**/*.ts", - "!src/EntryPoints/index.ts", - "!src/Domain/Validations/ValidationMessages.ts", - "!src/**/*.d.ts", - ], - coverageThreshold: { - global: { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - "./src/Domain/**/*.ts": { - branches: 80, - functions: 80, - lines: 80, - statements: 80, - }, - "./src/EntryPoints/**/*.ts": { - branches: 50, - functions: 70, - lines: 80, - statements: 80, - }, - }, -}; - -export default config; diff --git a/jest.setup.ts b/jest.setup.ts deleted file mode 100644 index 3cf524f..0000000 --- a/jest.setup.ts +++ /dev/null @@ -1,27 +0,0 @@ -import VARIAMOS_ORM from "./src/Infrastructure/VariamosORM"; - -// Silence console logs and errors during test executions to keep output clean -jest.spyOn(console, "log").mockImplementation(() => {}); -jest.spyOn(console, "error").mockImplementation(() => {}); -jest.spyOn(console, "warn").mockImplementation(() => {}); - -// Mock jet-logger globally to prevent process.stdout writes during tests -jest.mock("jet-logger", () => ({ - info: jest.fn(), - warn: jest.fn(), - err: jest.fn(), - imp: jest.fn(), - default: { - info: jest.fn(), - warn: jest.fn(), - err: jest.fn(), - imp: jest.fn(), - }, -})); - -// Gracefully close ORM database connections after tests run to avoid open handle leaks -afterAll(async () => { - if (VARIAMOS_ORM) { - await VARIAMOS_ORM.close(); - } -}); diff --git a/package-lock.json b/package-lock.json index 0e77bc2..fe216e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,15 +11,15 @@ "@variamosple/variamos-security": "^0.0.15", "axios": "^1.7.7", "bcrypt": "^6.0.0", - "cookie": "^1.0.2", + "cookie": "^2.0.1", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "dockerode": "^5.0.1", "dotenv": "^17.4.2", "express": "^5.2.1", - "google-auth-library": "^9.14.1", - "helmet": "^7.1.0", - "jet-logger": "^1.3.1", + "google-auth-library": "^11.0.0", + "helmet": "^8.3.0", + "jet-logger": "^2.2.3", "module-alias": "^2.2.3", "morgan": "^1.11.0", "multer": "^2.1.1", @@ -27,16 +27,17 @@ "pg": "^8.22.0", "sequelize": "^6.37.8", "ts-command-line-args": "^2.5.1", - "uuid": "^11.1.1", + "uuid": "^14.0.1", "ws": "^8.21.1" }, "devDependencies": { - "@commitlint/cli": "^20.5.3", - "@commitlint/config-conventional": "^20.5.3", + "@biomejs/biome": "^1.9.4", + "@commitlint/cli": "^21.0.0", + "@commitlint/config-conventional": "^21.0.0", "@stryker-mutator/core": "^9.6.1", - "@stryker-mutator/jest-runner": "^9.6.1", "@stryker-mutator/typescript-checker": "^9.6.1", - "@types/bcrypt": "^5.0.2", + "@stryker-mutator/vitest-runner": "^9.6.1", + "@types/bcrypt": "^6.0.0", "@types/cookie-parser": "^1.4.7", "@types/cors": "^2.8.17", "@types/dockerode": "^4.0.1", @@ -45,37 +46,46 @@ "@types/jest": "^30.0.0", "@types/morgan": "^1.9.9", "@types/multer": "^2.1.0", - "@types/node": "^22.5.0", + "@types/node": "^24.0.0", "@types/nodemailer": "^8.0.0", "@types/supertest": "^7.2.0", "@types/ws": "^8.18.1", - "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", - "cspell": "^9.8.0", + "@vitest/coverage-v8": "^3.0.5", + "cspell": "^10.0.1", "dependency-cruiser": "^18.1.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.5.6", "fs-extra": "^11.4.0", "husky": "^9.1.7", - "jest": "^30.4.2", - "jest-mock-extended": "^4.0.1", "knip": "^6.24.0", "lint-staged": "^17.3.0", "nodemon": "^3.1.14", - "prettier": "^3.9.6", "supertest": "^7.2.2", - "ts-jest": "^29.4.11", "ts-node": "^10.9.2", + "tsc-alias": "^1.8.10", "tsconfig-paths": "^4.2.0", - "typescript": "^5.5.4" + "tsx": "^4.19.2", + "typescript": "^5.8.2", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5", + "vitest-mock-extended": "^2.0.1" }, "engines": { "node": ">=24.0.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -420,61 +430,6 @@ "@babel/core": "^7.0.0-0" } }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-decorators": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", @@ -491,48 +446,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", - "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", @@ -549,116 +462,6 @@ "@babel/core": "^7.0.0-0" } }, - "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": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", @@ -820,142 +623,455 @@ "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", "license": "Apache-2.0" }, - "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/@commitlint/cli": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.5.3.tgz", - "integrity": "sha512-OJdL0EXWD5y9LPa0nr/geOwzaS8BsdaybKkcloB0JgsguGxNv2R+hC2FTPqrAcprg35zF33KOQerY0x8W1aesA==", + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/format": "^20.5.0", - "@commitlint/lint": "^20.5.3", - "@commitlint/load": "^20.5.3", - "@commitlint/read": "^20.5.0", - "@commitlint/types": "^20.5.0", - "tinyexec": "^1.0.0", - "yargs": "^17.0.0" - }, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", "bin": { - "commitlint": "cli.js" + "biome": "bin/biome" }, "engines": { - "node": ">=v18" + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" } }, - "node_modules/@commitlint/config-conventional": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.5.3.tgz", - "integrity": "sha512-j34Qqeaa152chJgz2ysyk0BCpHenJn1lV0Rx0VXf8k3ccQcED+48EZrzMvo9jLmJUyBrrBwvu89I+2er4gW7QQ==", + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "conventional-changelog-conventionalcommits": "^9.2.0" - }, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" } }, - "node_modules/@commitlint/config-validator": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.5.0.tgz", - "integrity": "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==", + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "ajv": "^8.11.0" - }, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" } }, - "node_modules/@commitlint/ensure": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.5.3.tgz", - "integrity": "sha512-4i4AgNvH62owG9MwSiWKrle7HGNpBHHdLnWFIp5fTsHUYe5kRuh15t08L/0pdbbrRk8JKXQxxN4hZQcn+szkrw==", + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "es-toolkit": "^1.46.0" - }, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" } }, - "node_modules/@commitlint/execute-rule": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", - "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" } }, - "node_modules/@commitlint/format": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.5.0.tgz", - "integrity": "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==", + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "picocolors": "^1.1.1" - }, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" } }, - "node_modules/@commitlint/is-ignored": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.5.0.tgz", - "integrity": "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==", + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "semver": "^7.6.0" - }, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=v18" + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@commitlint/cli": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-21.2.1.tgz", + "integrity": "sha512-blsZGe29hJ72VGEFVl72IVYX+1vsfINpjA9yWQA6i7OKD/McGEOXg08sKIRKjFk4JvzhV/9n0l3i6NooPLTNfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-conventional": "^21.2.0", + "@commitlint/format": "^21.2.0", + "@commitlint/lint": "^21.2.0", + "@commitlint/load": "^21.2.0", + "@commitlint/read": "^21.2.1", + "@commitlint/types": "^21.2.0", + "tinyexec": "^1.0.0", + "yargs": "^18.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/cli/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@commitlint/cli/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@commitlint/cli/node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@commitlint/cli/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@commitlint/cli/node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/yargs": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^8.2.1", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@commitlint/cli/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-21.2.0.tgz", + "integrity": "sha512-Qf8WRDVcyVd14if6VTWenebxFbKnVnbzPUJjlzjkyJGeHK2xCGd63Dr1XZzj0plXKQb9P0BfOxoc1HVeCo2BWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^21.2.0", + "conventional-changelog-conventionalcommits": "^10.0.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-21.2.0.tgz", + "integrity": "sha512-t7AzNHAKeIdo/3NRGwzpufKHsKkPHmFs/56N2Fnsh0/r0rGtnQzTxk6vnFgjaGr4hdSQKNB50/KAhR9Yk4LJKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^21.2.0", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/ensure": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-21.2.0.tgz", + "integrity": "sha512-76IF9vDNS13lAzEEik9eKwzt8f9hYhWiwVXZ2AnyLCz5/f511FsEQ3pw1X3/zSQpdRLQU7i5qDMVKyXi1GWjSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^21.2.0", + "es-toolkit": "^1.46.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-21.0.1.tgz", + "integrity": "sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/format": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-21.2.0.tgz", + "integrity": "sha512-c4q64xaav2U83t7k7RyzJerBZurPer7FxUOY0RL5L/6CZijZ7K+s6HIBGIghj0ey1P2+seRX0J9XQYtDued6tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^21.2.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-21.2.0.tgz", + "integrity": "sha512-4/eB0vBN7L88O/oC4ajAEqi7j2ZfNgxl/+11RfAV9YosejZgDXhY2C9VcHnHJhOzPLoSy5P3Mg/46kqeyJfXKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^21.2.0", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=22.12.0" } }, "node_modules/@commitlint/lint": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.5.3.tgz", - "integrity": "sha512-M7JbWBNr2gXKaPc4i/KipsuW1gkDHpj35KPjWtKy3Z+2AQw5wu1gBi1LIO0uoaij67CqY4K8PxPZSGens4evCw==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-21.2.0.tgz", + "integrity": "sha512-ceO5dp9pLjEZ6y6qbq/uXWXDPykqqlTsyzoQ0NzecpisSJhK3kTy9qzQoPeJuWG/IMNdV1lO0RgmzqoAlSi1uw==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/is-ignored": "^20.5.0", - "@commitlint/parse": "^20.5.0", - "@commitlint/rules": "^20.5.3", - "@commitlint/types": "^20.5.0" + "@commitlint/is-ignored": "^21.2.0", + "@commitlint/parse": "^21.2.0", + "@commitlint/rules": "^21.2.0", + "@commitlint/types": "^21.2.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/load": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.5.3.tgz", - "integrity": "sha512-1FDZWuKyu98Myb8i7Tp31jPU2rZpOwAdYRyJcy2KoGg7Xk2A+bgHN8smhMaaNSNkmE8fwt53BokywZq8Gv/5XQ==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-21.2.0.tgz", + "integrity": "sha512-RjlzWQqruRwIenJEfZtq7kG97co97nKoHpflE5YnF61tDLXxHPrdWImgzw6VL6MlFyaOcVlk74eBV8ZQmc3oIA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/execute-rule": "^20.0.0", - "@commitlint/resolve-extends": "^20.5.3", - "@commitlint/types": "^20.5.0", + "@commitlint/config-validator": "^21.2.0", + "@commitlint/execute-rule": "^21.0.1", + "@commitlint/resolve-extends": "^21.2.0", + "@commitlint/types": "^21.2.0", "cosmiconfig": "^9.0.1", "cosmiconfig-typescript-loader": "^6.1.0", "es-toolkit": "^1.46.0", @@ -963,139 +1079,137 @@ "picocolors": "^1.1.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/message": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", - "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-21.2.0.tgz", + "integrity": "sha512-YxGoiXD/HXNXLJPrQwE5poXa+XH0CBEm+mdvbHQP0g6MV/dmJyUFCzPNzZbxL93GvZ70TmtTK0Z0/IBpAqHv8g==", "dev": true, "license": "MIT", "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/parse": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.5.0.tgz", - "integrity": "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-21.2.0.tgz", + "integrity": "sha512-QHWxG4d0PLTF634/AdyZ0MQS+CLn5YOuJlCFhMMlSGKFxzYGUetkHBj18xgBD+6fVzUrA2lrCdi/vlS2f/oYXg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/types": "^20.5.0", - "conventional-changelog-angular": "^8.2.0", - "conventional-commits-parser": "^6.3.0" + "@commitlint/types": "^21.2.0", + "conventional-changelog-angular": "^9.0.0", + "conventional-commits-parser": "^7.0.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/read": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.5.0.tgz", - "integrity": "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==", + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-21.2.1.tgz", + "integrity": "sha512-hUW7EJQnNTL0vPOmVMNK4CrnrNBN0nN+JJHReFkdHO5y4iyHeEmTBwuC15OCqUTjxWo7idnH1LftfpWVIaPWIA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/top-level": "^20.4.3", - "@commitlint/types": "^20.5.0", - "git-raw-commits": "^5.0.0", - "minimist": "^1.2.8", + "@commitlint/top-level": "^21.2.0", + "@commitlint/types": "^21.2.0", + "@conventional-changelog/git-client": "^3.0.0", "tinyexec": "^1.0.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/resolve-extends": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.5.3.tgz", - "integrity": "sha512-+ogW9v/u9JqpvAgTrLra/YTFo0KkjU6iNblF89pPsj4NebNc+DAWctsludwezI8YnsjBmfHpApSwcXprN/f/ew==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-21.2.0.tgz", + "integrity": "sha512-4O/1j51+79Wth9s/MGxt/5gs0XYLDgNlYpltQfhAvLE0itusLKs9zruxbiNg1oOkmkb9L9L4USYGjEj7n87NxA==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/types": "^20.5.0", + "@commitlint/config-validator": "^21.2.0", + "@commitlint/types": "^21.2.0", "es-toolkit": "^1.46.0", "global-directory": "^5.0.0", - "import-meta-resolve": "^4.0.0", "resolve-from": "^5.0.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/rules": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.3.tgz", - "integrity": "sha512-MPlMnb9D3wbszYMp+1hPtuhtPJndRo6I6yfkZVA4+jR8w7Kqp0u2u/Y+gzbaItx5Lltq5rw7FSZQWJMoXUC4NQ==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-21.2.0.tgz", + "integrity": "sha512-C2yXMNpiB8ETZKfx5JD8+ExgF8vTU1VQMKPSUUYwqKpw9oJWQBrlXBpdU038mj2WPjof7o9UzFpmTyBeGMZwZg==", "dev": true, "license": "MIT", "dependencies": { - "@commitlint/ensure": "^20.5.3", - "@commitlint/message": "^20.4.3", - "@commitlint/to-lines": "^20.0.0", - "@commitlint/types": "^20.5.0" + "@commitlint/ensure": "^21.2.0", + "@commitlint/message": "^21.2.0", + "@commitlint/to-lines": "^21.0.1", + "@commitlint/types": "^21.2.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/to-lines": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", - "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-21.0.1.tgz", + "integrity": "sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==", "dev": true, "license": "MIT", "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/top-level": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", - "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-21.2.0.tgz", + "integrity": "sha512-Y5gmQ+KxzqCrBFJfLvFEPvvwD3LDiNZoTT2yeFBm96M8qhmqSzQc5DvX3rheAaAMjyIvMXOCLS/mWfdpONsjyQ==", "dev": true, "license": "MIT", "dependencies": { "escalade": "^3.2.0" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@commitlint/types": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.5.0.tgz", - "integrity": "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==", + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-21.2.0.tgz", + "integrity": "sha512-7zVFCDB2reMvJH5dmbKnOQPjZEvjdJTH8jc0U/PIPU1r3/+vf5pD1HlfitV2MWsWXrvu7u39iY1lyLUPOaN0Gw==", "dev": true, "license": "MIT", "dependencies": { - "conventional-commits-parser": "^6.3.0", + "conventional-commits-parser": "^7.0.0", "picocolors": "^1.1.1" }, "engines": { - "node": ">=v18" + "node": ">=22.12.0" } }, "node_modules/@conventional-changelog/git-client": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.7.0.tgz", - "integrity": "sha512-j7A8/LBEQ+3rugMzPXoKYzyUPpw/0CBQCyvtTR7Lmu4olG4yRC/Tfkq79Mr3yuPs0SUitlO2HwGP3gitMJnRFw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-3.1.1.tgz", + "integrity": "sha512-w/q+UIVdWQMgXlziPIYfPlyDud+H8kcvSCzDQQoc/gid7yZzb6eNfAkNN4UlEcS2cVVh924jevsOIb36d0In2g==", "dev": true, "license": "MIT", "dependencies": { - "@simple-libs/child-process-utils": "^1.0.0", - "@simple-libs/stream-utils": "^1.2.0", + "@simple-libs/child-process-utils": "^2.0.0", + "@simple-libs/stream-utils": "^2.0.0", "semver": "^7.5.2" }, "engines": { - "node": ">=18" + "node": ">=22" }, "peerDependencies": { - "conventional-commits-filter": "^5.0.0", - "conventional-commits-parser": "^6.4.0" + "conventional-commits-filter": "^6.0.1", + "conventional-commits-parser": "^7.1.2" }, "peerDependenciesMeta": { "conventional-commits-filter": { @@ -1106,10 +1220,20 @@ } } }, + "node_modules/@conventional-changelog/template": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@conventional-changelog/template/-/template-1.2.1.tgz", + "integrity": "sha512-TzlTVpKPjaqW6qOYjQcYUDuGsLCNsvFHVBXkYGTAnf5V37jCWrE5haKNXzz0WZUtVHjrpV76L1buANjwXMfT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" + } + }, "node_modules/@cspell/cspell-bundled-dicts": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.8.0.tgz", - "integrity": "sha512-MpXFpVyBPfJQ1YuVotljqUaGf6lWuf+fuWBBgs0PHFYTSjRPWuIxviAaCDnup/CJLLH60xQL4IlcQe4TOjzljw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-10.0.1.tgz", + "integrity": "sha512-WvkSDNX4Uyyj/ZgbPO6L38iFNMfK1EqsH1FteRiI2qLz6QZMXRFrIt12OqiWIplzZDDaVpBH9FCJOPJll0fjCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1174,86 +1298,86 @@ "@cspell/dict-zig": "^1.0.0" }, "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-json-reporter": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.8.0.tgz", - "integrity": "sha512-nqUaSo9T7l8KrE22gc7ZIs+zvP7ak1i7JqGdRs8sGvh2Ijqj43qYQLePgb1b/vm8a1bavnc51m+vf05hpd3g3Q==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-10.0.1.tgz", + "integrity": "sha512-/nes1RGILec3WCBcoMOd0byNTBtnJuPaVz/+ZzqYkLtY7x58VMcBG5kyP6hPyN8cIwjRADE/SR43gwdXuqk/FA==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/cspell-types": "9.8.0" + "@cspell/cspell-types": "10.0.1" }, "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-performance-monitor": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-performance-monitor/-/cspell-performance-monitor-9.8.0.tgz", - "integrity": "sha512-IsrXYzn23yJICIQ915ACdf+2lNEcFNTu5BIQt3khHOsGVvZ9/AZYpu9Dk825vUyZG7RHg2Oi6dYNiJtULG4ouQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-performance-monitor/-/cspell-performance-monitor-10.0.1.tgz", + "integrity": "sha512-9tVcHXwRnbazUv4WSG0h3MqV4+LgmLNgSALAQUflPPW0EMxTf7C4Dmv9cgxJyCEQrdnVKCr58nPPaahhz9LJUg==", "dev": true, "license": "MIT", "engines": { - "node": ">=20.18" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-pipe": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.8.0.tgz", - "integrity": "sha512-ISEUD8PHYkd2Ktafc6hFfIXdGKYUvthA09NbwwZsWmOqYyk4wWKHZKqyyxD+BcrFwOyMOJcD8OEvIjkRQp2SJw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-10.0.1.tgz", + "integrity": "sha512-HPeXMD9AZ3V/qPkvQaPcak+C7cJ2z7JTHN8smd6J8L2aThLRky2cHc2OyeaHPSHB7WA47b4z2n5u5nawZhv5VQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-resolver": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.8.0.tgz", - "integrity": "sha512-PZJj56BZpKfMxOzWkyt7b+aIXObe+8Ku/zLI4xDXPSuQPENbHBFHfPIZx68CyGEkanKxZ1ewKVx/FT1FUy+wDA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-10.0.1.tgz", + "integrity": "sha512-PIzkZHD1fGUQx1XteK2d1iQ0Mzq/maYcoB4jkvAiiR6WqP3MWYNKFdI9z+R5pOq5KgMfW+5Ig1q0oSR6h8irlA==", "dev": true, "license": "MIT", "dependencies": { "global-directory": "^5.0.0" }, "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-service-bus": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.8.0.tgz", - "integrity": "sha512-P45sd2nqwcqhulBBbQnZB/JNcobecTrP4Ky3vmEq0cprsvavc+ZoHF9U2Ql5ghMSUzjrF2n1aNzZ8cH4IlsnKg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-10.0.1.tgz", + "integrity": "sha512-y6NcIGP2IdXaBL4PVH8vxsr7K27wzz3Ech87UtUtrDSXAiVEOvXgAIknEOUVp59rTlUE8Rn4IRURC6f/hgMyfw==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-types": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.8.0.tgz", - "integrity": "sha512-7Ge4UD6SCA49Tcc3+GTlz3Xn4cqVUAXtDO0u9IeHvJgkN3Me2Rw2GB/CtGmhKST3YeEeZMX7ww09TdHMUJlehw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-10.0.1.tgz", + "integrity": "sha512-kLgLShnWADDVreKC63pBrWkcvxgZzFIfO34Jhx/SWfuOIA3cD8AXT+HjyuLfoGJ7mUb58hv2kUziKzEy4INb1w==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/cspell-worker": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/cspell-worker/-/cspell-worker-9.8.0.tgz", - "integrity": "sha512-W8FLdE3MXPLbWtAXciILQhk9CHd6Mt+HRjZHM8m+dwE1Bc2TAjUai8kIxsdhHUq58p7gYY2ekr5sg1uYOUgTAA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/cspell-worker/-/cspell-worker-10.0.1.tgz", + "integrity": "sha512-L2bJerfuYOls2wEknm8FmynLtj/G7O4UqX9I/HznRggEW6i2yZIxagDetpVDNowpyavNHJ3SJtUFiyMiZc16Sw==", "dev": true, "license": "MIT", "dependencies": { - "cspell-lib": "9.8.0" + "cspell-lib": "10.0.1" }, "engines": { - "node": ">=20.18" + "node": ">=22.18.0" } }, "node_modules/@cspell/dict-ada": { @@ -1682,57 +1806,57 @@ "license": "MIT" }, "node_modules/@cspell/dynamic-import": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.8.0.tgz", - "integrity": "sha512-wMgb32lqG9g6lCipUQsY9Bk5idXPDz7wvzOqEsU1M2HmNYmdE1wfPoRpfQfsVL965iG3+6h8QLr2+8FKpweFEQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-10.0.1.tgz", + "integrity": "sha512-mP1gdq00aIcH8HxNMqnH11X6BKxLcneDtFgl/ecjIKnaGKwi44m8AndP5Kr4ODaYdl8UUw9O3dJh7KaQXnLHZQ==", "dev": true, "license": "MIT", "dependencies": { - "@cspell/url": "9.8.0", + "@cspell/url": "10.0.1", "import-meta-resolve": "^4.2.0" }, "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/filetypes": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.8.0.tgz", - "integrity": "sha512-yHvtYn9qt6zykua77sNzTcf7HrG/dpo/+2pCMGSrfSrQypSNT6FUFvMS04W7kwhP86U1GkCjppNykXuoH3cqug==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-10.0.1.tgz", + "integrity": "sha512-Z5S35giU5IW49fBBq6BksUbE8PC4IYPfaKuwl5Nl9jkf/OkAKiBmCowKX45NzRUQInwK/GSqqIUifrNeI6LdLw==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/rpc": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/rpc/-/rpc-9.8.0.tgz", - "integrity": "sha512-t4lHEa254W+PePXNQ1noW7QhQxz/mhsJ9X8LEt0ILzBbPWCJzN+JuaM7EiolIPiwxtfxpMwKx9482kt4eTja7A==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/rpc/-/rpc-10.0.1.tgz", + "integrity": "sha512-axSRKv3zEAmBm66iD/FV/MPmE4/Yf7c3PZiwTW894Yd3iEhtn3KPKeTrqQ2/tDrhB1Z2qTsap/Hue0MK4o5WXg==", "dev": true, "license": "MIT", "engines": { - "node": ">=20.18" + "node": ">=22.18.0" } }, "node_modules/@cspell/strong-weak-map": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.8.0.tgz", - "integrity": "sha512-HocksAqZ0JcWA5oWO7TIlOCftXVGkPGzbeFlCRRrjJpZmYQH+4NdeEXyQC6T89NGocp45td/CgyBcAaFMy1N9w==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-10.0.1.tgz", + "integrity": "sha512-lenN1DVyPi8nJLSMSJJ670ddTjyiruLueuSZO1qLcxBqUhgxDt/mALu9N/1m6WdOVcg6m/5cLiZVg2KOo2UzRw==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspell/url": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.8.0.tgz", - "integrity": "sha512-LY1lFiZLTQF/ma1ilfKmRmFmEOw0RfYhyl0UMhY7/d93b+kiDMhxP/9Qir4+5LyiRncaE3++ZcWno9Hya+ssRg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-10.0.1.tgz", + "integrity": "sha512-abYYgI29wJhWIfWTYrYuzRYDcHQUQ1N5ylnhxYn1NJnIQMqUWGLbDmt12JABtZ+R6h6UNatQrS7rhP86etvJyQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.18.0" } }, "node_modules/@cspotcode/source-map-support": { @@ -1793,274 +1917,519 @@ "tslib": "^2.4.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", - "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 4" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/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==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@grpc/grpc-js": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz", - "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.8.0", - "@js-sdsl/ordered-map": "^4.4.2" - }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.10.0" + "node": ">=18" } }, - "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", - "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.5.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.10.0" + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-3-Clause" + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@inquirer/ansi": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", - "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + "node": ">=18" } }, - "node_modules/@inquirer/checkbox": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz", - "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^2.0.7", - "@inquirer/core": "^11.2.1", - "@inquirer/figures": "^2.0.7", - "@inquirer/type": "^4.0.7" - }, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz", + "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@inquirer/ansi": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", + "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz", + "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.7", + "@inquirer/core": "^11.2.1", + "@inquirer/figures": "^2.0.7", + "@inquirer/type": "^4.0.7" + }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" }, @@ -2417,680 +2786,478 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "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==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@jest/diff-sequences": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", "dev": true, "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/@jest/expect-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@jest/get-type": "30.1.0" }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", - "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "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", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/@jest/pattern": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "@types/node": "*", + "jest-regex-util": "30.4.0" }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "@sinclair/typebox": "^0.34.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/@jest/types": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jest/console": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", - "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", + "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": { - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "slash": "^3.0.0" - }, + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=6.0.0" } }, - "node_modules/@jest/core": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", - "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/pattern": "30.4.0", - "@jest/reporters": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "exit-x": "^0.2.2", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-changed-files": "30.4.1", - "jest-config": "30.4.2", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-resolve-dependencies": "30.4.2", - "jest-runner": "30.4.2", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "jest-watcher": "30.4.1", - "pretty-format": "30.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", - "dev": true, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-mock": "30.4.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^22.20 || ^24.12 || >=25" } }, - "node_modules/@jest/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "expect": "30.4.1", - "jest-snapshot": "30.4.1" + "@tybys/wasm-util": "^0.10.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, - "node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", - "@sinonjs/fake-timers": "^15.4.0", - "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 8" } }, - "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==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 8" } }, - "node_modules/@jest/globals": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", - "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/types": "30.4.1", - "jest-mock": "30.4.1" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 8" } }, - "node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "node_modules/@oxc-parser/binding-android-arm-eabi": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.142.0.tgz", + "integrity": "sha512-ZiRGDutGsv1G6bL/ozy/koC0Sv39T1DqyoC4KD1DOy9ZoACm1O5UWhEK2c02Qdk+4lfLVkvFa/mQ0fm/4h1BtQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jest/reporters": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", - "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.142.0.tgz", + "integrity": "sha512-WZkvGRLNQTz8lR9zP5nLjUdlroRCopBu3g9zF1p/laE6DzT1UbQo8Rdz5MWhaJUPYg/6gp+jo7HUgsyKaN1FtQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.142.0.tgz", + "integrity": "sha512-l4khS8LQOOVYsGRVARo1gSaCT/aBSceUVXgtovWc2+drnxVuDr082WA3OCHVdVzIz5JIrP/y9CWsSKxBDNmYGg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jest/snapshot-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", - "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.142.0.tgz", + "integrity": "sha512-QBsNF3nqlXmcH2B1YOPqQYmCJoy4HuIjUxGbBO/k5JAJUl68ghU2psRY2zPk+RyBaWqKP/qfL4oaFgEMCdwskA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.142.0.tgz", + "integrity": "sha512-b7Q7m4Cqc6XqNhri3R+QhU+GVy646Pn+bkdhrDdWym/Fdi0ZUa+d73H9dm5H91JtbtAQ/z1d8XKMW3oOV8a4tQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jest/test-result": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", - "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.142.0.tgz", + "integrity": "sha512-3riVS5IhdH3uCZj1Y9ftDQlR0dvLsIlw/edrRqk8JhgNd5K0XSs+UBtgh50N13CAlW9/TXj6sVGXaKNBocd0Yg==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jest/console": "30.4.1", - "@jest/types": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", - "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", - "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.142.0.tgz", + "integrity": "sha512-NmXUOpgpTSkhl795TiXmWppTwmSJ92RC1qvD6e4XOF+slgmo3e6Ah+kEu+6AN8s7NAOEwqGmir58MgSQSWmBSA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.3" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=23.5.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", - "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" - } - }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-android-arm-eabi": { + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.142.0.tgz", - "integrity": "sha512-ZiRGDutGsv1G6bL/ozy/koC0Sv39T1DqyoC4KD1DOy9ZoACm1O5UWhEK2c02Qdk+4lfLVkvFa/mQ0fm/4h1BtQ==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.142.0.tgz", + "integrity": "sha512-gc0EXsKtXgerujmU2Bql3u1L1HsSQ2774R83idq/FoNMPVV/RY/1ErFsvnit7KoiP/sLvzQixeUo4Ut0ic0wmw==", "cpu": [ - "arm" + "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-android-arm64": { + "node_modules/@oxc-parser/binding-linux-arm64-musl": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.142.0.tgz", - "integrity": "sha512-WZkvGRLNQTz8lR9zP5nLjUdlroRCopBu3g9zF1p/laE6DzT1UbQo8Rdz5MWhaJUPYg/6gp+jo7HUgsyKaN1FtQ==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.142.0.tgz", + "integrity": "sha512-F2XvmWSE0uWpie+jHKKIFgdVOe9ypGhkEZxKx5DuW215K6cbAC274yYaPkcM7EqY4Df3Weyhpcz3lsURyH2LVg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-darwin-arm64": { + "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.142.0.tgz", - "integrity": "sha512-l4khS8LQOOVYsGRVARo1gSaCT/aBSceUVXgtovWc2+drnxVuDr082WA3OCHVdVzIz5JIrP/y9CWsSKxBDNmYGg==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.142.0.tgz", + "integrity": "sha512-wLMbT21U/QxknQsk+VvNF0b9D2/aGWhcaQQQ+VYlE8FwD5+GoWZIPPXNzyHmkYyhm0KB3itL+TBavjMatqNnYA==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-darwin-x64": { + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.142.0.tgz", - "integrity": "sha512-QBsNF3nqlXmcH2B1YOPqQYmCJoy4HuIjUxGbBO/k5JAJUl68ghU2psRY2zPk+RyBaWqKP/qfL4oaFgEMCdwskA==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.142.0.tgz", + "integrity": "sha512-+G8F/4ckwT7FCJV4H2bt09xEzJbjNCfuL4Sp1AYNaFtFMVtgIGMuJlteT82U+K0UIZ/DzAR/LDlMFnEuajG7Kw==", "cpu": [ - "x64" + "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-freebsd-x64": { + "node_modules/@oxc-parser/binding-linux-riscv64-musl": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.142.0.tgz", - "integrity": "sha512-b7Q7m4Cqc6XqNhri3R+QhU+GVy646Pn+bkdhrDdWym/Fdi0ZUa+d73H9dm5H91JtbtAQ/z1d8XKMW3oOV8a4tQ==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.142.0.tgz", + "integrity": "sha512-hTsHtTLxMAfCo+rpF5K3qZJKW2NpPN/CHd4mYB3y7XlSdspHkd2gehDIofP64AacA9nWQw2tY3O7wR6UY8IVOA==", "cpu": [ - "x64" + "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ - "freebsd" + "linux" ], "engines": { "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.142.0.tgz", - "integrity": "sha512-3riVS5IhdH3uCZj1Y9ftDQlR0dvLsIlw/edrRqk8JhgNd5K0XSs+UBtgh50N13CAlW9/TXj6sVGXaKNBocd0Yg==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.142.0.tgz", + "integrity": "sha512-6y7qYY3TCUDYjqswImdTGl92y+KA/80twALegQPN27kfY+bG7Ib1+L3jbmrCZQx6wrVnai9IPsEZp07I0hx7JQ==", "cpu": [ - "arm" + "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3100,154 +3267,17 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "node_modules/@oxc-parser/binding-linux-x64-gnu": { "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.142.0.tgz", - "integrity": "sha512-NmXUOpgpTSkhl795TiXmWppTwmSJ92RC1qvD6e4XOF+slgmo3e6Ah+kEu+6AN8s7NAOEwqGmir58MgSQSWmBSA==", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.142.0.tgz", + "integrity": "sha512-i69kAWU+2LgoH5bR+zWiiu+UzAw7Oxkwv7COeJTeY19pn4e70nKQcr9Pm6cL2Z0Z54d+gl9qADlK/0yyuCPiBA==", "cpu": [ - "arm" + "x64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.142.0.tgz", - "integrity": "sha512-gc0EXsKtXgerujmU2Bql3u1L1HsSQ2774R83idq/FoNMPVV/RY/1ErFsvnit7KoiP/sLvzQixeUo4Ut0ic0wmw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.142.0.tgz", - "integrity": "sha512-F2XvmWSE0uWpie+jHKKIFgdVOe9ypGhkEZxKx5DuW215K6cbAC274yYaPkcM7EqY4Df3Weyhpcz3lsURyH2LVg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.142.0.tgz", - "integrity": "sha512-wLMbT21U/QxknQsk+VvNF0b9D2/aGWhcaQQQ+VYlE8FwD5+GoWZIPPXNzyHmkYyhm0KB3itL+TBavjMatqNnYA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.142.0.tgz", - "integrity": "sha512-+G8F/4ckwT7FCJV4H2bt09xEzJbjNCfuL4Sp1AYNaFtFMVtgIGMuJlteT82U+K0UIZ/DzAR/LDlMFnEuajG7Kw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-musl": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.142.0.tgz", - "integrity": "sha512-hTsHtTLxMAfCo+rpF5K3qZJKW2NpPN/CHd4mYB3y7XlSdspHkd2gehDIofP64AacA9nWQw2tY3O7wR6UY8IVOA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.142.0.tgz", - "integrity": "sha512-6y7qYY3TCUDYjqswImdTGl92y+KA/80twALegQPN27kfY+bG7Ib1+L3jbmrCZQx6wrVnai9IPsEZp07I0hx7JQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.142.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.142.0.tgz", - "integrity": "sha512-i69kAWU+2LgoH5bR+zWiiu+UzAw7Oxkwv7COeJTeY19pn4e70nKQcr9Pm6cL2Z0Z54d+gl9qADlK/0yyuCPiBA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -3690,19 +3720,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", - "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -3760,1351 +3777,1245 @@ "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", "license": "BSD-3-Clause" }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@simple-libs/child-process-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", - "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@simple-libs/stream-utils": "^1.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@simple-libs/stream-utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", - "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@sinclair/typebox": { - "version": "0.34.52", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", - "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", - "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/api": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-9.6.1.tgz", - "integrity": "sha512-g8VNoFWQWbx0pdal3Vt8jVCZW+v3sc3gi94iI0GVtVgUGTqphAjJF6EAruPTx0lqvtonsaAxn5TD36hcG1d6Wg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "mutation-testing-metrics": "3.7.3", - "mutation-testing-report-schema": "3.7.3", - "tslib": "~2.8.0", - "typed-inject": "~5.0.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@stryker-mutator/core": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-9.6.1.tgz", - "integrity": "sha512-WMgnvf+Wyh/yiruhNZwc8w8DlzmmjXhPjSn5MR8RhAXzlnWji8TQrUYgBUkHk9bEgSaIlB3KZHm37iiU5Q2cLQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@inquirer/prompts": "^8.0.0", - "@stryker-mutator/api": "9.6.1", - "@stryker-mutator/instrumenter": "9.6.1", - "@stryker-mutator/util": "9.6.1", - "ajv": "~8.18.0", - "chalk": "~5.6.0", - "commander": "~14.0.0", - "diff-match-patch": "1.0.5", - "emoji-regex": "~10.6.0", - "execa": "~9.6.0", - "json-rpc-2.0": "^1.7.0", - "lodash.groupby": "~4.6.0", - "minimatch": "~10.2.4", - "mutation-server-protocol": "~0.4.0", - "mutation-testing-elements": "3.7.3", - "mutation-testing-metrics": "3.7.3", - "mutation-testing-report-schema": "3.7.3", - "npm-run-path": "~6.0.0", - "progress": "~2.0.3", - "rxjs": "~7.8.1", - "semver": "^7.6.3", - "source-map": "~0.7.4", - "tree-kill": "~1.2.2", - "tslib": "2.8.1", - "typed-inject": "~5.0.0", - "typed-rest-client": "~2.3.0" - }, - "bin": { - "stryker": "bin/stryker.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@stryker-mutator/core/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/core/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@stryker-mutator/instrumenter": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-9.6.1.tgz", - "integrity": "sha512-5K8wH4Pthly25c2uKKik4Dfcoeou7sbJdFS6u3QIYHlulgFVDJwtEMWTZGkZfs7IiUEXIDNa0keRACq5jn5AvA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/core": "~7.29.0", - "@babel/generator": "~7.29.0", - "@babel/parser": "~7.29.0", - "@babel/plugin-proposal-decorators": "~7.29.0", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/preset-typescript": "~7.28.0", - "@stryker-mutator/api": "9.6.1", - "@stryker-mutator/util": "9.6.1", - "angular-html-parser": "~10.4.0", - "semver": "~7.7.0", - "tslib": "2.8.1", - "weapon-regex": "~1.3.2" - }, - "engines": { - "node": ">=20.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/instrumenter/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/jest-runner": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/jest-runner/-/jest-runner-9.6.1.tgz", - "integrity": "sha512-nIrIndfWwdweYkIcxJmyBTpl84nrXs9AE6A8vzEwwzUGvDb9kVvwBPfpEajtdAkjwPceH0pPuVrPkotvqcgYqQ==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stryker-mutator/api": "9.6.1", - "@stryker-mutator/util": "9.6.1", - "semver": "~7.7.0", - "tslib": "~2.8.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@stryker-mutator/core": "9.6.1" - } + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/jest-runner/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/typescript-checker": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/typescript-checker/-/typescript-checker-9.6.1.tgz", - "integrity": "sha512-dCFJDoFixFe7cbilsukb7a5jpn9JRSPef7/vgx+xfaf4gPf/neDVbci8E/YSvxmcFveuPHdeUxioocA1CKZqrg==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stryker-mutator/api": "9.6.1", - "@stryker-mutator/util": "9.6.1", - "semver": "~7.7.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@stryker-mutator/core": "9.6.1", - "typescript": ">=3.6" - } + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/typescript-checker/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@stryker-mutator/util": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-9.6.1.tgz", - "integrity": "sha512-Lk/ALVctJjFv1vvwR+CFoKzDCWvsBlq7flDUnmnpuwTrGbm156EdZD1Jjq4o8KdOap0ezUZqQNE9OAI1m2+pUQ==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "Apache-2.0" + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "MIT" + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "MIT" + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", - "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } + "os": [ + "openbsd" + ] }, - "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==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } + "optional": true, + "os": [ + "openharmony" + ] }, - "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==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "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==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "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==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@types/bcrypt": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", - "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } + "license": "MIT" }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@simple-libs/child-process-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-2.0.0.tgz", + "integrity": "sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@simple-libs/stream-utils": "^2.0.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" } }, - "node_modules/@types/cookie-parser": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.10.tgz", - "integrity": "sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg==", + "node_modules/@simple-libs/stream-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-2.0.0.tgz", + "integrity": "sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ==", "dev": true, "license": "MIT", - "peerDependencies": { - "@types/express": "*" + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" } }, - "node_modules/@types/cookiejar": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", - "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "dev": true, "license": "MIT" }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/debug": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", - "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", - "license": "MIT", + "node_modules/@stryker-mutator/api": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-9.6.1.tgz", + "integrity": "sha512-g8VNoFWQWbx0pdal3Vt8jVCZW+v3sc3gi94iI0GVtVgUGTqphAjJF6EAruPTx0lqvtonsaAxn5TD36hcG1d6Wg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@types/ms": "*" + "mutation-testing-metrics": "3.7.3", + "mutation-testing-report-schema": "3.7.3", + "tslib": "~2.8.0", + "typed-inject": "~5.0.0" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/docker-modem": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz", - "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==", + "node_modules/@stryker-mutator/core": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-9.6.1.tgz", + "integrity": "sha512-WMgnvf+Wyh/yiruhNZwc8w8DlzmmjXhPjSn5MR8RhAXzlnWji8TQrUYgBUkHk9bEgSaIlB3KZHm37iiU5Q2cLQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/node": "*", - "@types/ssh2": "*" + "@inquirer/prompts": "^8.0.0", + "@stryker-mutator/api": "9.6.1", + "@stryker-mutator/instrumenter": "9.6.1", + "@stryker-mutator/util": "9.6.1", + "ajv": "~8.18.0", + "chalk": "~5.6.0", + "commander": "~14.0.0", + "diff-match-patch": "1.0.5", + "emoji-regex": "~10.6.0", + "execa": "~9.6.0", + "json-rpc-2.0": "^1.7.0", + "lodash.groupby": "~4.6.0", + "minimatch": "~10.2.4", + "mutation-server-protocol": "~0.4.0", + "mutation-testing-elements": "3.7.3", + "mutation-testing-metrics": "3.7.3", + "mutation-testing-report-schema": "3.7.3", + "npm-run-path": "~6.0.0", + "progress": "~2.0.3", + "rxjs": "~7.8.1", + "semver": "^7.6.3", + "source-map": "~0.7.4", + "tree-kill": "~1.2.2", + "tslib": "2.8.1", + "typed-inject": "~5.0.0", + "typed-rest-client": "~2.3.0" + }, + "bin": { + "stryker": "bin/stryker.js" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/dockerode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-4.0.1.tgz", - "integrity": "sha512-cmUpB+dPN955PxBEuXE3f6lKO1hHiIGYJA46IVF3BJpNsZGvtBDcRnlrHYHtOH/B6vtDOyl2kZ2ShAu3mgc27Q==", + "node_modules/@stryker-mutator/core/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { - "@types/docker-modem": "*", - "@types/node": "*", - "@types/ssh2": "*" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@types/express": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "node_modules/@stryker-mutator/core/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/serve-static": "^2" + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz", - "integrity": "sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==", + "node_modules/@stryker-mutator/instrumenter": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-9.6.1.tgz", + "integrity": "sha512-5K8wH4Pthly25c2uKKik4Dfcoeou7sbJdFS6u3QIYHlulgFVDJwtEMWTZGkZfs7IiUEXIDNa0keRACq5jn5AvA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@babel/core": "~7.29.0", + "@babel/generator": "~7.29.0", + "@babel/parser": "~7.29.0", + "@babel/plugin-proposal-decorators": "~7.29.0", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/preset-typescript": "~7.28.0", + "@stryker-mutator/api": "9.6.1", + "@stryker-mutator/util": "9.6.1", + "angular-html-parser": "~10.4.0", + "semver": "~7.7.0", + "tslib": "2.8.1", + "weapon-regex": "~1.3.2" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/fs-extra": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", - "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "node_modules/@stryker-mutator/instrumenter/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/jsonfile": "*", - "@types/node": "*" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true, - "license": "MIT" - }, - "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==", + "node_modules/@stryker-mutator/typescript-checker": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/typescript-checker/-/typescript-checker-9.6.1.tgz", + "integrity": "sha512-dCFJDoFixFe7cbilsukb7a5jpn9JRSPef7/vgx+xfaf4gPf/neDVbci8E/YSvxmcFveuPHdeUxioocA1CKZqrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@stryker-mutator/api": "9.6.1", + "@stryker-mutator/util": "9.6.1", + "semver": "~7.7.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@stryker-mutator/core": "9.6.1", + "typescript": ">=3.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==", + "node_modules/@stryker-mutator/typescript-checker/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/jest": { - "version": "30.0.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", - "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "node_modules/@stryker-mutator/util": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-9.6.1.tgz", + "integrity": "sha512-Lk/ALVctJjFv1vvwR+CFoKzDCWvsBlq7flDUnmnpuwTrGbm156EdZD1Jjq4o8KdOap0ezUZqQNE9OAI1m2+pUQ==", "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^30.0.0", - "pretty-format": "^30.0.0" - } + "license": "Apache-2.0" }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "node_modules/@stryker-mutator/vitest-runner": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/vitest-runner/-/vitest-runner-9.6.1.tgz", + "integrity": "sha512-eyUHTCf3Ui+SUn/tpFJwzw6MV391kyBLZk/cDHFUfKFELqKMLbvd7e81axArlApKqO6cOnLfrxlwED+2SRN0ow==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/node": "*" + "@stryker-mutator/api": "9.6.1", + "@stryker-mutator/util": "9.6.1", + "semver": "^7.7.4", + "tslib": "~2.8.0" + }, + "engines": { + "node": ">=14.18.0" + }, + "peerDependencies": { + "@stryker-mutator/core": "9.6.1", + "vitest": ">=2.0.0" } }, - "node_modules/@types/methods": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", - "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", "dev": true, "license": "MIT" }, - "node_modules/@types/morgan": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", - "integrity": "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==", + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, - "node_modules/@types/multer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.2.0.tgz", - "integrity": "sha512-3U1troeqGV8Ntp7Q3klwf4zr23VEoqYVocYXaswm9+8z3O9UHDYAqLxjJ/h550iRADTjKdOdhhasXw6gD6kYtg==", + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } + "license": "MIT" }, - "node_modules/@types/node": { - "version": "22.20.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", - "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, - "node_modules/@types/nodemailer": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz", - "integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@types/node": "*" + "tslib": "^2.4.0" } }, - "node_modules/@types/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "node_modules/@types/bcrypt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-6.0.0.tgz", + "integrity": "sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" } - }, - "node_modules/@types/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { - "@types/http-errors": "*", + "@types/connect": "*", "@types/node": "*" } }, - "node_modules/@types/ssh2": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.5.tgz", - "integrity": "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "^18.11.18" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/@types/ssh2/node_modules/@types/node": { - "version": "18.19.130", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", - "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "@types/node": "*" } }, - "node_modules/@types/ssh2/node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "node_modules/@types/cookie-parser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.10.tgz", + "integrity": "sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peerDependencies": { + "@types/express": "*" + } }, - "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==", + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", "dev": true, "license": "MIT" }, - "node_modules/@types/superagent": { - "version": "8.1.11", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.11.tgz", - "integrity": "sha512-KA7srSW/HENDtOw9DOqaFLgWuMqN9WgjEw62lh9dpvRaZDkhdOkazASd7X7i2eMUYLHa1U37ZttnePsH5zTDHw==", + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "dev": true, "license": "MIT", "dependencies": { - "@types/cookiejar": "^2.1.5", - "@types/methods": "^1.1.4", - "@types/node": "*", - "form-data": "^4.0.0" + "@types/node": "*" } }, - "node_modules/@types/supertest": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.1.tgz", - "integrity": "sha512-4CbBvoYVLHL7+yhbYrZET0vsvuyXTC05aRe7dNQkwMzm56auceoy6Yu3K50uZmwfHna1os3CMSgM/3QVkUtPTw==", - "dev": true, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { - "@types/methods": "^1.1.4", - "@types/superagent": "^8.1.0" + "@types/ms": "*" } }, - "node_modules/@types/validator": { - "version": "13.15.10", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", - "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, "license": "MIT" }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "node_modules/@types/docker-modem": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz", + "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/node": "*", + "@types/ssh2": "*" } }, - "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==", + "node_modules/@types/dockerode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-4.0.1.tgz", + "integrity": "sha512-cmUpB+dPN955PxBEuXE3f6lKO1hHiIGYJA46IVF3BJpNsZGvtBDcRnlrHYHtOH/B6vtDOyl2kZ2ShAu3mgc27Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/yargs-parser": "*" + "@types/docker-modem": "*", + "@types/node": "*", + "@types/ssh2": "*" } }, - "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==", + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "dev": true, "license": "MIT" }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", - "integrity": "sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==", + "node_modules/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/type-utils": "8.66.0", - "@typescript-eslint/utils": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.66.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.66.0.tgz", - "integrity": "sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==", + "node_modules/@types/express-serve-static-core": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz", + "integrity": "sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", - "integrity": "sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==", + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.66.0", - "@typescript-eslint/types": "^8.66.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" + "@types/jsonfile": "*", + "@types/node": "*" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", - "integrity": "sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==", + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", - "integrity": "sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==", + "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", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", - "integrity": "sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==", + "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": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0", - "debug": "^4.4.3", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.66.0.tgz", - "integrity": "sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", - "integrity": "sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==", + "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": { - "@typescript-eslint/project-service": "8.66.0", - "@typescript-eslint/tsconfig-utils": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" + "@types/istanbul-lib-report": "*" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.66.0.tgz", - "integrity": "sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==", + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" + "expect": "^30.0.0", + "pretty-format": "^30.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", - "integrity": "sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==", + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.66.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/node": "*" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } + "license": "MIT" }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", - "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "node_modules/@types/morgan": { + "version": "1.9.10", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", + "integrity": "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "@types/node": "*" + } }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", - "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", - "cpu": [ - "arm" - ], + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/multer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.2.0.tgz", + "integrity": "sha512-3U1troeqGV8Ntp7Q3klwf4zr23VEoqYVocYXaswm9+8z3O9UHDYAqLxjJ/h550iRADTjKdOdhhasXw6gD6kYtg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@types/express": "*" + } }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", - "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "undici-types": "~7.18.0" + } }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", - "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", - "cpu": [ - "arm64" - ], + "node_modules/@types/nodemailer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz", + "integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@types/node": "*" + } }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", - "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", - "cpu": [ - "x64" - ], + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "license": "MIT" }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", - "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", - "cpu": [ - "x64" - ], + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "license": "MIT" }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", - "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", - "cpu": [ - "arm" - ], + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/node": "*" + } }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", - "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", - "cpu": [ - "arm" - ], + "node_modules/@types/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*" + } }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", - "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", - "cpu": [ - "arm64" - ], + "node_modules/@types/ssh2": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.5.tgz", + "integrity": "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/node": "^18.11.18" + } }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", - "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", - "cpu": [ - "arm64" - ], + "node_modules/@types/ssh2/node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, - "libc": [ - "musl" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "undici-types": "~5.26.4" + } }, - "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", - "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", - "cpu": [ - "loong64" - ], + "node_modules/@types/ssh2/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/@unrs/resolver-binding-linux-loong64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", - "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", - "cpu": [ - "loong64" - ], + "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, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", - "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", - "cpu": [ - "ppc64" - ], + "node_modules/@types/superagent": { + "version": "8.1.11", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.11.tgz", + "integrity": "sha512-KA7srSW/HENDtOw9DOqaFLgWuMqN9WgjEw62lh9dpvRaZDkhdOkazASd7X7i2eMUYLHa1U37ZttnePsH5zTDHw==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" + } }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", - "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", - "cpu": [ - "riscv64" - ], + "node_modules/@types/supertest": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.1.tgz", + "integrity": "sha512-4CbBvoYVLHL7+yhbYrZET0vsvuyXTC05aRe7dNQkwMzm56auceoy6Yu3K50uZmwfHna1os3CMSgM/3QVkUtPTw==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", - "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", - "cpu": [ - "riscv64" - ], + "node_modules/@types/validator": { + "version": "13.15.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", + "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "dev": true, - "libc": [ - "musl" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/node": "*" + } }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", - "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", - "cpu": [ - "s390x" - ], + "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, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/yargs-parser": "*" + } }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", - "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", - "cpu": [ - "x64" - ], + "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, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" + }, + "node_modules/@variamosple/variamos-security": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/@variamosple/variamos-security/-/variamos-security-0.0.15.tgz", + "integrity": "sha512-NfuXvff8ztAu5PNc9aHdVKsL994qx4ESsowEQq/yuvaDK8cWSgYQUFMcuLkrB8daNOXdRiMFytRztdXGMSos1w==", + "license": "MIT", + "dependencies": { + "@variamosple/variamos-security": "file:", + "node-jose": "^2.2.0" + } }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", - "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", - "cpu": [ - "x64" - ], + "node_modules/@variamosple/variamos-security/node_modules/@variamosple/variamos-security": { + "resolved": "node_modules/@variamosple/variamos-security", + "link": true + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz", + "integrity": "sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==", "dev": true, - "libc": [ - "musl" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^1.0.2", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.17", + "magicast": "^0.3.5", + "std-env": "^3.9.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "3.2.7", + "vitest": "3.2.7" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } }, - "node_modules/@unrs/resolver-binding-openharmony-arm64": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", - "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", - "cpu": [ - "arm64" - ], + "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", - "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", - "cpu": [ - "wasm32" - ], + "node_modules/@vitest/coverage-v8/node_modules/test-exclude": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", + "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", "dev": true, - "license": "MIT", - "optional": true, + "license": "ISC", "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^10.2.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "node_modules/@vitest/expect": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "node_modules/@vitest/mocker": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "@vitest/spy": "3.2.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "node_modules/@vitest/pretty-format": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", - "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", - "cpu": [ - "arm64" - ], + "node_modules/@vitest/runner": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@vitest/utils": "3.2.7", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", - "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", - "cpu": [ - "ia32" - ], + "node_modules/@vitest/snapshot": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", - "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", - "cpu": [ - "x64" - ], + "node_modules/@vitest/spy": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } }, - "node_modules/@variamosple/variamos-security": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/@variamosple/variamos-security/-/variamos-security-0.0.15.tgz", - "integrity": "sha512-NfuXvff8ztAu5PNc9aHdVKsL994qx4ESsowEQq/yuvaDK8cWSgYQUFMcuLkrB8daNOXdRiMFytRztdXGMSos1w==", + "node_modules/@vitest/utils": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "dev": true, "license": "MIT", "dependencies": { - "@variamosple/variamos-security": "file:", - "node-jose": "^2.2.0" + "@vitest/pretty-format": "3.2.7", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@variamosple/variamos-security/node_modules/@variamosple/variamos-security": { - "resolved": "node_modules/@variamosple/variamos-security", - "link": true - }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -5213,35 +5124,6 @@ "node": ">= 14" } }, - "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": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/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": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -5317,6 +5199,19 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/argue-cli": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/argue-cli/-/argue-cli-3.1.0.tgz", + "integrity": "sha512-DhBpBfXL4SS2uC0N922MMajKR3CdrTG0u2or1PNYgXMsrSzViJrbtvT0nCLlLGUI0plam/ZZCs7aAauHtW9thw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } + }, "node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", @@ -5326,13 +5221,6 @@ "node": ">=6" } }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, "node_modules/array-timsort": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", @@ -5340,6 +5228,16 @@ "dev": true, "license": "MIT" }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -5356,6 +5254,35 @@ "safer-buffer": "~2.1.0" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz", + "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5374,105 +5301,6 @@ "proxy-from-env": "^2.1.0" } }, - "node_modules/babel-jest": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", - "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "30.4.1", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.4.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" - } - }, - "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": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", - "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/babel__core": "^7.20.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "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": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-jest": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", - "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "30.4.0", - "babel-preset-current-node-syntax": "^1.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" - } - }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -5696,29 +5524,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 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": { - "node-int64": "^0.4.0" - } - }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -5784,6 +5589,16 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -5823,16 +5638,6 @@ "node": ">=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": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001809", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", @@ -5854,6 +5659,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5899,16 +5721,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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": { - "node": ">=10" - } - }, "node_modules/chardet": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", @@ -5916,6 +5728,16 @@ "dev": true, "license": "MIT" }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -5976,30 +5798,6 @@ "node": ">=8" } }, - "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/clear-module": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.3.tgz", - "integrity": "sha512-XdLrg7BnbXKntyrbs2dNjDN9CVoTQ+WV0i7jT5/r9ahzAaSDSzC9e2OVZB/QVwbxBb1/1AeObzjlxsYk5HFvww==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^2.0.0", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -6061,24 +5859,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "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": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "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" - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6098,9 +5878,9 @@ "license": "MIT" }, "node_modules/colors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", - "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "license": "MIT", "engines": { "node": ">=0.1.90" @@ -6248,9 +6028,9 @@ } }, "node_modules/comment-json": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.2.tgz", - "integrity": "sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-5.0.0.tgz", + "integrity": "sha512-uiqLcOiVDJtBP8WGkZHEP+FZIhTzP1dxvn59EfoYUi9gqupjrBWVQkO2atDrbnKPwLeotFYDsuNb26uBMqB+hw==", "dev": true, "license": "MIT", "dependencies": { @@ -6261,17 +6041,6 @@ "node": ">= 6" } }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", @@ -6282,13 +6051,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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" - }, "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", @@ -6327,46 +6089,46 @@ } }, "node_modules/conventional-changelog-angular": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", - "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-9.2.1.tgz", + "integrity": "sha512-oWSL6ZhnXbYraOFTK3PgRAQJ8fADDAEv5K6AdeyQPLvjFmhG8+ejL0jZZp/R7vTmGJaBvZEE+sE7dB4bCv7sAw==", "dev": true, "license": "ISC", "dependencies": { - "compare-func": "^2.0.0" + "@conventional-changelog/template": "^1.2.1" }, "engines": { - "node": ">=18" + "node": ">=22" } }, "node_modules/conventional-changelog-conventionalcommits": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.1.tgz", - "integrity": "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-10.2.1.tgz", + "integrity": "sha512-n4Kr1HFMTf3iMbES0TMxKIcYtUUv4rKqyQQp2JwfOEfFCOfGT3Tq4mCyJ8S9/YPyWhydjfKrrvnyl+gCjA+mJQ==", "dev": true, "license": "ISC", "dependencies": { - "compare-func": "^2.0.0" + "@conventional-changelog/template": "^1.2.1" }, "engines": { - "node": ">=18" + "node": ">=22" } }, "node_modules/conventional-commits-parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz", - "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-7.1.2.tgz", + "integrity": "sha512-O+x4N2yH+ijvqWlIyTHsXTAP+algNWgGbjY2duCe8w2vUMvUB95cLRslCPfTMQyLAKlet3bhZTdu6ozn4M+QJQ==", "dev": true, "license": "MIT", "dependencies": { - "@simple-libs/stream-utils": "^1.2.0", - "meow": "^13.0.0" + "@simple-libs/stream-utils": "^2.0.0", + "argue-cli": "^3.1.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" }, "engines": { - "node": ">=18" + "node": ">=22" } }, "node_modules/convert-source-map": { @@ -6377,12 +6139,12 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", "license": "MIT", "engines": { - "node": ">=18" + "node": ">=22" }, "funding": { "type": "opencollective", @@ -6494,1127 +6256,725 @@ "optional": true, "dependencies": { "buildcheck": "~0.0.6", - "nan": "^2.19.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cspell": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.8.0.tgz", - "integrity": "sha512-qL0VErMSn8BDxaPxcV+9uenffgjPS+5Jfz+m4rCsvYjzLwr7AaaJBWWSV2UiAe/4cturae8n8qzxiGnbbazkRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-json-reporter": "9.8.0", - "@cspell/cspell-performance-monitor": "9.8.0", - "@cspell/cspell-pipe": "9.8.0", - "@cspell/cspell-types": "9.8.0", - "@cspell/cspell-worker": "9.8.0", - "@cspell/dynamic-import": "9.8.0", - "@cspell/url": "9.8.0", - "ansi-regex": "^6.2.2", - "chalk": "^5.6.2", - "chalk-template": "^1.1.2", - "commander": "^14.0.3", - "cspell-config-lib": "9.8.0", - "cspell-dictionary": "9.8.0", - "cspell-gitignore": "9.8.0", - "cspell-glob": "9.8.0", - "cspell-io": "9.8.0", - "cspell-lib": "9.8.0", - "fast-json-stable-stringify": "^2.1.0", - "flatted": "^3.4.2", - "semver": "^7.7.4", - "tinyglobby": "^0.2.15" - }, - "bin": { - "cspell": "bin.mjs", - "cspell-esm": "bin.mjs" - }, - "engines": { - "node": ">=20.18" - }, - "funding": { - "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" - } - }, - "node_modules/cspell-config-lib": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.8.0.tgz", - "integrity": "sha512-gMJBAgYPvvO+uDFLUcGWaTu6/e+r8mm4GD4rQfWa/yV4F9fj+yOYLIMZqLWRvT1moHZX1FxyVvUbJcmZ1gfebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-types": "9.8.0", - "comment-json": "^4.6.2", - "smol-toml": "^1.6.1", - "yaml": "^2.8.3" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-dictionary": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.8.0.tgz", - "integrity": "sha512-QW4hdkWcrxZA1QNqi26U0S/U3/V+tKCm7JaaesEJW2F6Ao+23AbHVwidyAVtXaEhGkn6PxB+epKrrAa6nE69qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-performance-monitor": "9.8.0", - "@cspell/cspell-pipe": "9.8.0", - "@cspell/cspell-types": "9.8.0", - "cspell-trie-lib": "9.8.0", - "fast-equals": "^6.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-gitignore": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.8.0.tgz", - "integrity": "sha512-SDUa1DmSfT20+JH7XtyzcEL9KfurneoR/XbmlrtPQZP/LUHXh3yz4x/0vFIkEFXNWdSckY0QdWTz8DaxClCf4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/url": "9.8.0", - "cspell-glob": "9.8.0", - "cspell-io": "9.8.0" - }, - "bin": { - "cspell-gitignore": "bin.mjs" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-glob": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.8.0.tgz", - "integrity": "sha512-Uvj/iHXs+jpsJyIEnhEoJTWXb1GVyZ9T05L5JFtZfsQNXrh8SRDQPscjxbg4okKr63N7WevfioQum/snHNYvmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/url": "9.8.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-grammar": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.8.0.tgz", - "integrity": "sha512-01XMq2vhPS0Gvxnfed9uvOwH+3cXddHYxW0PwCE+SZdcC6TN8yM6glByuLt1qFustAmQVE5GSr7uAY9o4pZQRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-pipe": "9.8.0", - "@cspell/cspell-types": "9.8.0" - }, - "bin": { - "cspell-grammar": "bin.mjs" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-io": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.8.0.tgz", - "integrity": "sha512-JINaEWQEzR4f2upwdZOFcft+nBvQgizJfrOLszxG3p+BIzljnGklqE/nUtLFZpBu0oMJvuM/Fd+GsWor0yP7Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-service-bus": "9.8.0", - "@cspell/url": "9.8.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-lib": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.8.0.tgz", - "integrity": "sha512-G2TtPcye5QE5ev3YgWq42UOJLpTZ6naO/47oIm+jmeSYbgnbcOSThnEE7uMycx+TTNOz/vJVFpZmQyt0bWCftw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspell/cspell-bundled-dicts": "9.8.0", - "@cspell/cspell-performance-monitor": "9.8.0", - "@cspell/cspell-pipe": "9.8.0", - "@cspell/cspell-resolver": "9.8.0", - "@cspell/cspell-types": "9.8.0", - "@cspell/dynamic-import": "9.8.0", - "@cspell/filetypes": "9.8.0", - "@cspell/rpc": "9.8.0", - "@cspell/strong-weak-map": "9.8.0", - "@cspell/url": "9.8.0", - "clear-module": "^4.1.2", - "cspell-config-lib": "9.8.0", - "cspell-dictionary": "9.8.0", - "cspell-glob": "9.8.0", - "cspell-grammar": "9.8.0", - "cspell-io": "9.8.0", - "cspell-trie-lib": "9.8.0", - "env-paths": "^4.0.0", - "gensequence": "^8.0.8", - "import-fresh": "^3.3.1", - "resolve-from": "^5.0.0", - "vscode-languageserver-textdocument": "^1.0.12", - "vscode-uri": "^3.1.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/cspell-lib/node_modules/env-paths": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-4.0.0.tgz", - "integrity": "sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-safe-filename": "^0.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cspell-trie-lib": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.8.0.tgz", - "integrity": "sha512-GXIyqxya8QLp6SjKsAN9w3apvt1Ww7GKcZvTBaP76OfLoyb1QC6unwmObY2cZs1manCntGwHrgU6vFNuXnTzpw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@cspell/cspell-types": "9.8.0" - } - }, - "node_modules/cspell/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", + "nan": "^2.19.0" + }, "engines": { - "node": ">=4.0.0" + "node": ">=10.0.0" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true, "license": "MIT" }, - "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==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" + "node": ">= 8" } }, - "node_modules/dependency-cruiser": { - "version": "18.1.1", - "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-18.1.1.tgz", - "integrity": "sha512-qK29b8kBW60KI1Qvf2w93823AE55lJuXV21iUw9tAMiZudgA95mR2j/EzqsploqS8d8uavTzn1IVoKDSilLD4g==", + "node_modules/cspell": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-10.0.1.tgz", + "integrity": "sha512-Gg6w/flT3fKfl3la62hfTnhtNnDQ+9mU7kUhVqw/axl/Ms4oENw0oJMkWFIoj4f6nL/SDPz7KcPXd2XbkKFNmQ==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "8.18.0", - "acorn-jsx": "5.3.2", - "acorn-jsx-walk": "2.0.0", - "acorn-loose": "8.5.2", - "acorn-walk": "8.3.5", - "commander": "15.0.0", - "enhanced-resolve": "5.24.5", - "ignore": "7.0.6", - "interpret": "3.1.1", - "is-installed-globally": "1.0.0", - "json5": "2.2.3", - "picomatch": "4.0.5", - "prompts": "2.4.2", - "rechoir": "0.8.0", - "safe-regex": "2.1.1", - "semver": "7.8.5", - "tsconfig-paths-webpack-plugin": "4.2.0", - "watskeburt": "6.0.0" + "@cspell/cspell-json-reporter": "10.0.1", + "@cspell/cspell-performance-monitor": "10.0.1", + "@cspell/cspell-pipe": "10.0.1", + "@cspell/cspell-types": "10.0.1", + "@cspell/cspell-worker": "10.0.1", + "@cspell/dynamic-import": "10.0.1", + "@cspell/url": "10.0.1", + "ansi-regex": "^6.2.2", + "chalk": "^5.6.2", + "chalk-template": "^1.1.2", + "commander": "^14.0.3", + "cspell-config-lib": "10.0.1", + "cspell-dictionary": "10.0.1", + "cspell-gitignore": "10.0.1", + "cspell-glob": "10.0.1", + "cspell-io": "10.0.1", + "cspell-lib": "10.0.1", + "fast-json-stable-stringify": "^2.1.0", + "flatted": "^3.4.2", + "semver": "^7.8.1", + "tinyglobby": "^0.2.16" }, "bin": { - "depcruise": "bin/dependency-cruise.mjs", - "depcruise-baseline": "bin/depcruise-baseline.mjs", - "depcruise-fmt": "bin/depcruise-fmt.mjs", - "depcruise-wrap-stream-in-html": "bin/wrap-stream-in-html.mjs", - "dependency-cruise": "bin/dependency-cruise.mjs", - "dependency-cruiser": "bin/dependency-cruise.mjs" + "cspell": "bin.mjs", + "cspell-esm": "bin.mjs" }, "engines": { - "node": "^22||^24||>=26" - } - }, - "node_modules/dependency-cruiser/node_modules/commander": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", - "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=22.12.0" + "node": ">=22.18.0" + }, + "funding": { + "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "node_modules/cspell-config-lib": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-10.0.1.tgz", + "integrity": "sha512-hMpo/0j6k7pbiqrLDOLJKD2IGP9XwhjKf2miiM6p84Xeo4nyuFZaxxDCQ68R851HSYFrrdltgpoipMbj1h2Tnw==", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "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", + "@cspell/cspell-types": "10.0.1", + "comment-json": "^5.0.0", + "smol-toml": "^1.6.1", + "yaml": "^2.9.0" + }, "engines": { - "node": ">=8" + "node": ">=22.18.0" } }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "node_modules/cspell-dictionary": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-10.0.1.tgz", + "integrity": "sha512-3cZ659vgsZWkzGQJR/sNqGDVt/OnvTSieLKI76V++4t1bHJfochb9ZrrwsuMsb1VPGiyqClUP1/O6WrefF/FVg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true, - "license": "BSD-3-Clause", + "@cspell/cspell-performance-monitor": "10.0.1", + "@cspell/cspell-pipe": "10.0.1", + "@cspell/cspell-types": "10.0.1", + "cspell-trie-lib": "10.0.1", + "fast-equals": "^6.0.0" + }, "engines": { - "node": ">=0.3.1" + "node": ">=22.18.0" } }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", + "node_modules/cspell-gitignore": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-10.0.1.tgz", + "integrity": "sha512-wN23U61Mx6qPJN3CesOmBU9vnbJ0jQm/ylK0iaVui3CcnO7Zzl5qLu5mPHUzGQGm8yso6qjyxqo16Ho7LpZGOQ==", "dev": true, - "license": "Apache-2.0" - }, - "node_modules/docker-modem": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.7.tgz", - "integrity": "sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==", - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "debug": "^4.1.1", - "readable-stream": "^3.5.0", - "split-ca": "^1.0.1", - "ssh2": "^1.15.0" + "@cspell/url": "10.0.1", + "cspell-glob": "10.0.1", + "cspell-io": "10.0.1" + }, + "bin": { + "cspell-gitignore": "bin.mjs" }, "engines": { - "node": ">= 8.0" + "node": ">=22.18.0" } }, - "node_modules/dockerode": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz", - "integrity": "sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==", - "license": "Apache-2.0", + "node_modules/cspell-glob": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-10.0.1.tgz", + "integrity": "sha512-7bII9J3aSSpZDwhx7w+zfQXbMxHZQ3be0ilUp5bHrsjz6o07v/NqOHMGcwKdPn1sw2dxDz9sv057xE5pqXnSdw==", + "dev": true, + "license": "MIT", "dependencies": { - "@balena/dockerignore": "^1.0.2", - "@grpc/grpc-js": "^1.11.1", - "@grpc/proto-loader": "^0.7.13", - "docker-modem": "^5.0.7", - "protobufjs": "^7.3.2", - "tar-fs": "^2.1.4" + "@cspell/url": "10.0.1", + "picomatch": "^4.0.4" }, "engines": { - "node": ">= 14.17" + "node": ">=22.18.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/cspell-grammar": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-10.0.1.tgz", + "integrity": "sha512-xC9AFYmaI9wsO//a7S5tdDGKGJVD5UEEsTg+Up2fi7lPfXIryisYmV6tePNL1SEg0idYss4ja8LUZ3Mib09BjQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "esutils": "^2.0.2" + "@cspell/cspell-pipe": "10.0.1", + "@cspell/cspell-types": "10.0.1" + }, + "bin": { + "cspell-grammar": "bin.mjs" }, "engines": { - "node": ">=6.0.0" + "node": ">=22.18.0" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/cspell-io": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-10.0.1.tgz", + "integrity": "sha512-8C2ka07faxflnaqEBO3pektS21XViE/SEHT7F5ZD1ou7FyMR5u3xawTBJSczClfsxLt/WYeztBYrpmGAjmjksw==", "dev": true, "license": "MIT", "dependencies": { - "is-obj": "^2.0.0" + "@cspell/cspell-service-bus": "10.0.1", + "@cspell/url": "10.0.1" }, "engines": { - "node": ">=8" + "node": ">=22.18.0" } }, - "node_modules/dotenv": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", - "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "node_modules/cspell-lib": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-10.0.1.tgz", + "integrity": "sha512-RpsIPiLzc4/YMW8BMRKpyJ81x439qjYWcqgdKeXnMkbKM88J9PexzutfFf/4v97v96KzfNitEzMpbI0uj8OeUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-bundled-dicts": "10.0.1", + "@cspell/cspell-performance-monitor": "10.0.1", + "@cspell/cspell-pipe": "10.0.1", + "@cspell/cspell-resolver": "10.0.1", + "@cspell/cspell-types": "10.0.1", + "@cspell/dynamic-import": "10.0.1", + "@cspell/filetypes": "10.0.1", + "@cspell/rpc": "10.0.1", + "@cspell/strong-weak-map": "10.0.1", + "@cspell/url": "10.0.1", + "cspell-config-lib": "10.0.1", + "cspell-dictionary": "10.0.1", + "cspell-glob": "10.0.1", + "cspell-grammar": "10.0.1", + "cspell-io": "10.0.1", + "cspell-trie-lib": "10.0.1", + "env-paths": "^4.0.0", + "gensequence": "^8.0.8", + "import-fresh": "^4.0.0", + "resolve-from": "^5.0.0", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-uri": "^3.1.0", + "xdg-basedir": "^5.1.0" }, - "funding": { - "url": "https://dotenvx.com" + "engines": { + "node": ">=22.18.0" } }, - "node_modules/dottie": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.7.tgz", - "integrity": "sha512-7lAK2A0b3zZr3UC5aE69CPdCFR4RHW1o2Dr74TqFykxkUCBXSRJum/yPc7g8zRHJqWKomPLHwFLLoUnn8PXXRg==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT" - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/cspell-lib/node_modules/env-paths": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-4.0.0.tgz", + "integrity": "sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==", + "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "is-safe-filename": "^0.1.0" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "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" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.402", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz", - "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==", - "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==", + "node_modules/cspell-lib/node_modules/import-fresh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-4.0.0.tgz", + "integrity": "sha512-Fpi660c7VPDM3fPKYovStd9IP1CPOikf6v/dGxJJMmHPcwYQIMJ4W7kO1avBYEpMqkCh+Dx3Ln6H7VYqgztLjw==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=22.15" }, "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "node_modules/cspell-trie-lib": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-10.0.1.tgz", + "integrity": "sha512-BFvhalSkRQFjKrZ//FKK7fRGrZFpifnxB5AwCkzsIsBZqicsfafcQ1xP21qpb0QqyV/IomjNgviG+tRJs+0rMw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=22.18.0" + }, + "peerDependencies": { + "@cspell/cspell-types": "10.0.1" + } }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "node_modules/cspell/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "engines": { + "node": ">= 12" } }, - "node_modules/enhanced-resolve": { - "version": "5.24.5", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", - "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", - "dev": true, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.3" + "ms": "^2.1.3" }, "engines": { - "node": ">=10.13.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", "engines": { "node": ">=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, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">=4.0.0" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=0.4.0" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 0.8" } }, - "node_modules/es-object-atoms": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", - "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "node_modules/dependency-cruiser": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-18.1.1.tgz", + "integrity": "sha512-qK29b8kBW60KI1Qvf2w93823AE55lJuXV21iUw9tAMiZudgA95mR2j/EzqsploqS8d8uavTzn1IVoKDSilLD4g==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0" + "acorn": "8.18.0", + "acorn-jsx": "5.3.2", + "acorn-jsx-walk": "2.0.0", + "acorn-loose": "8.5.2", + "acorn-walk": "8.3.5", + "commander": "15.0.0", + "enhanced-resolve": "5.24.5", + "ignore": "7.0.6", + "interpret": "3.1.1", + "is-installed-globally": "1.0.0", + "json5": "2.2.3", + "picomatch": "4.0.5", + "prompts": "2.4.2", + "rechoir": "0.8.0", + "safe-regex": "2.1.1", + "semver": "7.8.5", + "tsconfig-paths-webpack-plugin": "4.2.0", + "watskeburt": "6.0.0" + }, + "bin": { + "depcruise": "bin/dependency-cruise.mjs", + "depcruise-baseline": "bin/depcruise-baseline.mjs", + "depcruise-fmt": "bin/depcruise-fmt.mjs", + "depcruise-wrap-stream-in-html": "bin/wrap-stream-in-html.mjs", + "dependency-cruise": "bin/dependency-cruise.mjs", + "dependency-cruiser": "bin/dependency-cruise.mjs" }, "engines": { - "node": ">= 0.4" + "node": "^22||^24||>=26" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "node_modules/dependency-cruiser/node_modules/commander": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", + "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=22.12.0" } }, - "node_modules/es-toolkit": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", - "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==", + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", "dev": true, "license": "MIT", - "workspaces": [ - "docs", - "benchmarks", - "tests/types" - ] - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" } }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, + "node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=0.3.1" } }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } + "license": "Apache-2.0" }, - "node_modules/eslint-plugin-es": { + "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "license": "MIT", "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=8" + } + }, + "node_modules/docker-modem": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.7.tgz", + "integrity": "sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.15.0" }, - "peerDependencies": { - "eslint": ">=4.19.1" + "engines": { + "node": ">= 8.0" } }, - "node_modules/eslint-plugin-jest": { - "version": "29.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.0.tgz", - "integrity": "sha512-0WFBxDHlT2ratGQfnFQEVIsgQJ5cfd+0IV8Kc6U3X2onB8ATLG23voD2Ch5G9fCkEpCPmCMuzW0tbS0kYb8biw==", - "dev": true, - "license": "MIT", + "node_modules/dockerode": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz", + "integrity": "sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==", + "license": "Apache-2.0", "dependencies": { - "@typescript-eslint/utils": "^8.0.0" + "@balena/dockerignore": "^1.0.2", + "@grpc/grpc-js": "^1.11.1", + "@grpc/proto-loader": "^0.7.13", + "docker-modem": "^5.0.7", + "protobufjs": "^7.3.2", + "tar-fs": "^2.1.4" }, "engines": { - "node": "^20.12.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "jest": "*", - "typescript": ">=4.8.4 <8.0.0" + "node": ">= 14.17" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - }, - "typescript": { - "optional": true - } + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, + "node_modules/dottie": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.7.tgz", + "integrity": "sha512-7lAK2A0b3zZr3UC5aE69CPdCFR4RHW1o2Dr74TqFykxkUCBXSRJum/yPc7g8zRHJqWKomPLHwFLLoUnn8PXXRg==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-node/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, - "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "dev": true, - "license": "MIT", + "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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "safe-buffer": "^5.0.1" } }, - "node_modules/eslint-plugin-node/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": { - "node": ">= 4" - } + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, - "node_modules/eslint-plugin-node/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "node_modules/electron-to-chromium": { + "version": "1.5.402", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz", + "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "ISC" }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } + "license": "MIT" }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz", - "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==", - "dev": true, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.1", - "synckit": "^0.11.13" - }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } + "node": ">= 0.8" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "once": "^1.4.0" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "license": "Apache-2.0", "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=6" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "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": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "is-arrayish": "^0.2.1" } }, - "node_modules/eslint/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "dev": true, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">= 0.4" } }, - "node_modules/eslint/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, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { - "node": ">= 4" + "node": ">= 0.4" } }, - "node_modules/eslint/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==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, - "node_modules/eslint/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", + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "es-errors": "^1.3.0" }, "engines": { - "node": "*" + "node": ">= 0.4" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 0.4" } }, - "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==", + "node_modules/es-toolkit": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", + "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==", "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks", + "tests/types" + ] }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=0.10" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, - "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": { - "estraverse": "^5.2.0" - }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">=6" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "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": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">=4.0" + "node": ">=4" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" } }, "node_modules/etag": { @@ -7653,16 +7013,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "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": { - "node": ">= 0.8.0" - } - }, "node_modules/expect": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", @@ -7681,6 +7031,16 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", @@ -7755,13 +7115,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/fast-equals": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.2.tgz", @@ -7772,6 +7125,36 @@ "node": ">=6.0.0" } }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "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", @@ -7779,13 +7162,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", @@ -7847,16 +7223,6 @@ "reusify": "^1.0.4" } }, - "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": { - "bser": "2.1.1" - } - }, "node_modules/fd-package-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-2.0.0.tgz", @@ -7885,6 +7251,29 @@ } } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/figures": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", @@ -7901,19 +7290,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -7960,38 +7336,6 @@ "node": ">=4.0.0" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "node_modules/flatted": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", @@ -8089,6 +7433,18 @@ "node": ">=18.3.0" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/formidable": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", @@ -8146,13 +7502,6 @@ "node": ">=14.14" } }, - "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" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -8178,19 +7527,17 @@ } }, "node_modules/gaxios": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" + "node-fetch": "^3.3.2" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/gaxios/node_modules/agent-base": { @@ -8215,30 +7562,18 @@ "node": ">= 14" } }, - "node_modules/gaxios/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==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gcp-metadata": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", "license": "Apache-2.0", "dependencies": { - "gaxios": "^6.1.1", - "google-logging-utils": "^0.0.2", + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/gensequence": { @@ -8270,6 +7605,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -8294,16 +7642,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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": { - "node": ">=8.0.0" - } - }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -8347,24 +7685,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/git-raw-commits": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", - "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", - "deprecated": "Deprecated and no longer maintained. Use @conventional-changelog/git-client instead.", - "dev": true, - "license": "MIT", - "dependencies": { - "@conventional-changelog/git-client": "^2.6.0", - "meow": "^13.0.0" - }, - "bin": { - "git-raw-commits": "src/cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -8387,19 +7707,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/glob/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -8449,43 +7756,65 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.20.2" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/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": { + "node": ">= 4" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, "node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-11.0.0.tgz", + "integrity": "sha512-WC5gkb2pElGhZKgGx9r799trH3ZUx90ecgIOIMmgiiHS/gzO3r4vvFoQWuKI0QmR2xU5uee2M4hDUxRZDh/x7w==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", + "gaxios": "^7.1.4", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=22" } }, "node_modules/google-logging-utils": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -8510,58 +7839,6 @@ "dev": true, "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "license": "MIT", - "dependencies": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/handlebars": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/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": { - "node": ">=0.10.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -8611,12 +7888,15 @@ } }, "node_modules/helmet": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.2.0.tgz", - "integrity": "sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.3.0.tgz", + "integrity": "sha512-Qgpiaws3Sm30Av8Eah6sjMCZZwjlBu+E68rhpCWBshY1lb09HtLwj5GviX0OyQIn+ulUS0iX0AxN5n3tLZzz1w==", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" } }, "node_modules/html-escaper": { @@ -8755,19 +8035,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/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": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=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", @@ -8778,26 +8045,6 @@ "node": ">=4" } }, - "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": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/import-meta-resolve": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", @@ -8806,17 +8053,7 @@ "license": "MIT", "funding": { "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/inflection": { @@ -8828,18 +8065,6 @@ ], "license": "MIT" }, - "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": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -8930,16 +8155,6 @@ "node": ">=8" } }, - "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": { - "node": ">=6" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -9019,26 +8234,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -9114,23 +8309,6 @@ "node": ">=8" } }, - "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": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -9175,368 +8353,32 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", - "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "30.4.2", - "@jest/types": "30.4.1", - "import-local": "^3.2.0", - "jest-cli": "30.4.2" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", - "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.1.1", - "jest-util": "30.4.1", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-changed-files/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": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/jest-changed-files/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": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/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": { - "node": ">=10.17.0" - } - }, - "node_modules/jest-changed-files/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": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/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": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/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/jest-changed-files/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": { - "node": ">=6" - } - }, - "node_modules/jest-circus": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", - "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "co": "^4.6.0", - "dedent": "^1.6.0", - "is-generator-fn": "^2.1.0", - "jest-each": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "p-limit": "^3.1.0", - "pretty-format": "30.4.1", - "pure-rand": "^7.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-cli": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", - "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "30.4.2", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", - "chalk": "^4.1.2", - "exit-x": "^0.2.2", - "import-local": "^3.2.0", - "jest-config": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "yargs": "^17.7.2" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", - "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.4.0", - "@jest/test-sequencer": "30.4.1", - "@jest/types": "30.4.1", - "babel-jest": "30.4.1", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "deepmerge": "^4.3.1", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-circus": "30.4.2", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-runner": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "parse-json": "^5.2.0", - "pretty-format": "30.4.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "esbuild-register": ">=3.4.0", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "esbuild-register": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", - "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-each": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", - "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", - "chalk": "^4.1.2", - "jest-util": "30.4.1", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", - "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-mock": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { - "fsevents": "^2.3.3" + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jest-leak-detector": { + "node_modules/jest-diff": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", - "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "dev": true, "license": "MIT", "dependencies": { + "@jest/diff-sequences": "30.4.0", "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", "pretty-format": "30.4.1" }, "engines": { @@ -9596,40 +8438,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-mock-extended": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-4.0.1.tgz", - "integrity": "sha512-Q/4k/yefiv/Al3n755V9xDEwMiL+7LwkjRKjaORkgCdovZv00hF/D0QypLoqO+MVfrYkzCYa4BYlcEKA74iOgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.isequal": "^4.5.0", - "ts-essentials": "^10.1.1" - }, - "peerDependencies": { - "@jest/globals": "^28.0.0 || ^29.0.0 || ^30.0.0", - "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 || ^30.0.0", - "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" - } - }, - "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": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, "node_modules/jest-regex-util": { "version": "30.4.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", @@ -9640,141 +8448,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-resolve": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", - "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", - "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "30.4.0", - "jest-snapshot": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", - "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "30.4.1", - "@jest/environment": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-haste-map": "30.4.1", - "jest-leak-detector": "30.4.1", - "jest-message-util": "30.4.1", - "jest-resolve": "30.4.1", - "jest-runtime": "30.4.2", - "jest-util": "30.4.1", - "jest-watcher": "30.4.1", - "jest-worker": "30.4.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", - "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/globals": "30.4.1", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.4.1", - "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-util": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", @@ -9793,97 +8466,13 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-validate": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", - "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", - "camelcase": "^6.3.0", - "chalk": "^4.1.2", - "leven": "^3.1.0", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "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": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", - "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "jest-util": "30.4.1", - "string-length": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "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": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/jet-logger": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jet-logger/-/jet-logger-1.3.1.tgz", - "integrity": "sha512-BSsTm88Y7a+XtXKpZM71qm0ulH+bNI13rR+BzeQStfjpE/6n3fX3FZpKF/WZh52h1e6gEAOjuFlkmdzGBQnwPg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jet-logger/-/jet-logger-2.2.3.tgz", + "integrity": "sha512-/RDYgayCwNCDfz7BQ2A6q5c/W75dbLIgIR20+VwLRVqEUn0egklnrF/3lEXQfz2GyJkfyO9bBRvq0t9Jfdu2CQ==", "license": "MIT", "dependencies": { - "colors": "1.3.0" + "colors": "1.4.0" } }, "node_modules/jiti": { @@ -9955,13 +8544,6 @@ "bignumber.js": "^9.0.0" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, "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", @@ -9983,13 +8565,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -10037,16 +8612,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -10119,30 +8684,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -10174,22 +8715,6 @@ "yaml": "^2.9.0" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", @@ -10209,34 +8734,19 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "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/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -10247,6 +8757,28 @@ "yallist": "^3.0.2" } }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -10270,16 +8802,6 @@ "dev": true, "license": "ISC" }, - "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": { - "tmpl": "1.0.5" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10299,20 +8821,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/express" } }, "node_modules/merge-descriptors": { @@ -10327,12 +8836,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 8" + } }, "node_modules/methods": { "version": "1.1.2", @@ -10344,6 +8856,33 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/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": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -10382,16 +8921,6 @@ "url": "https://opencollective.com/express" } }, - "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": { - "node": ">=6" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -10618,6 +9147,20 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/mylas": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.14.tgz", + "integrity": "sha512-BzQguy9W9NJgoVn2mRWzbFrFWWztGCcng2QI9+41frfk+Athwgx3qhqhvStz7ExeUUu7Kzw427sNzHpEZNINog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, "node_modules/nan": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", @@ -10625,29 +9168,25 @@ "license": "MIT", "optional": true }, - "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==", + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "bin": { - "napi-postinstall": "lib/cli.js" + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -10657,13 +9196,6 @@ "node": ">= 0.6" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, "node_modules/node-addon-api": { "version": "8.9.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.1.tgz", @@ -10673,24 +9205,42 @@ "node": "^18 || ^20 || >= 21" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "license": "MIT", "dependencies": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/node-forge": { @@ -10713,13 +9263,6 @@ "node-gyp-build-test": "build-test.js" } }, - "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-jose": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", @@ -10923,40 +9466,6 @@ "wrappy": "1" } }, - "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": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/oxc-parser": { "version": "0.142.0", "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.142.0.tgz", @@ -11026,48 +9535,6 @@ "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -11092,16 +9559,16 @@ "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", - "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", + "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": { - "callsites": "^3.1.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/parse-json": { @@ -11145,26 +9612,6 @@ "node": ">= 0.8" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -11216,6 +9663,33 @@ "url": "https://opencollective.com/express" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/pg": { "version": "8.22.0", "resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz", @@ -11325,83 +9799,46 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "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": { - "node": ">= 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": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", + "node_modules/plimit-lit": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz", + "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "queue-lit": "^1.5.1" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "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==", + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14" } }, "node_modules/postgres-array": { @@ -11431,55 +9868,16 @@ "node": ">=0.10.0" } }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", - "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", - "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", - "dev": true, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "license": "MIT", "dependencies": { - "fast-diff": "^1.1.2" + "xtend": "^4.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, "node_modules/pretty-format": { @@ -11622,33 +10020,6 @@ "once": "^1.3.1" } }, - "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": { - "node": ">=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": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, "node_modules/qs": { "version": "6.15.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", @@ -11665,6 +10036,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-lit": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", + "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11802,19 +10183,6 @@ "regexp-tree": "bin/regexp-tree" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11856,19 +10224,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -11906,74 +10261,50 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "glob": "^7.1.3" + "@types/estree": "1.0.9" }, "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/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": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "rollup": "dist/bin/rollup" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/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": { - "brace-expansion": "^1.1.7" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "engines": { - "node": "*" + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" } }, "node_modules/router": { @@ -12291,6 +10622,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -12357,21 +10695,10 @@ "node": ">= 12" } }, - "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": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -12393,13 +10720,6 @@ "node": ">= 10.x" } }, - "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/ssh2": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", @@ -12440,6 +10760,13 @@ "node": ">=8" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -12449,6 +10776,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -12482,20 +10816,6 @@ "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", "license": "WTFPL OR MIT" }, - "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": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -12605,16 +10925,6 @@ "node": ">=8" } }, - "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": { - "node": ">=8" - } - }, "node_modules/strip-final-newline": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", @@ -12628,19 +10938,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "js-tokens": "^9.0.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/antfu" } }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/superagent": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", @@ -12712,22 +11029,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/synckit": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", - "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.3.6" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, "node_modules/table-layout": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", @@ -12803,78 +11104,10 @@ "node": ">=6" } }, - "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": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/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": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/test-exclude/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": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, @@ -12905,12 +11138,35 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, - "license": "BSD-3-Clause" + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -12950,12 +11206,6 @@ "nodetouch": "bin/nodetouch.js" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -12966,19 +11216,6 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-api-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", - "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, "node_modules/ts-command-line-args": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", @@ -13006,73 +11243,7 @@ "peerDependenciesMeta": { "typescript": { "optional": true - } - } - }, - "node_modules/ts-jest": { - "version": "29.4.12", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", - "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.9", - "json5": "^2.2.3", - "lodash.memoize": "^4.1.2", - "make-error": "^1.3.6", - "semver": "^7.8.5", - "type-fest": "^4.41.0", - "yargs-parser": "^21.1.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0 || ^30.0.0", - "@jest/types": "^29.0.0 || ^30.0.0", - "babel-jest": "^29.0.0 || ^30.0.0", - "jest": "^29.0.0 || ^30.0.0", - "jest-util": "^29.0.0 || ^30.0.0", - "typescript": ">=4.3 <7" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jest-util": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + } } }, "node_modules/ts-node": { @@ -13119,6 +11290,60 @@ } } }, + "node_modules/tsc-alias": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.9.1.tgz", + "integrity": "sha512-sFZdVFthH8uvdplPJrOYGOHcxu6UPtcAcY678JPwEQiMzgLZYFO7Qc/rzELp7ingTc+OxtzH6n+8Pn2eVQep6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "get-tsconfig": "^4.10.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + }, + "engines": { + "node": ">=16.20.2" + } + }, + "node_modules/tsc-alias/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "deprecated": "unmaintained", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -13167,6 +11392,25 @@ "dev": true, "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.23.11", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.11.tgz", + "integrity": "sha512-Ry2oTEUnhBdeEdWIztY8kf3/nBGnPnjMLVGL0YfdRXMORuPER5NlKmayqxtxRxwB1xBN+RivRaJfe7PM1rtiyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -13183,42 +11427,6 @@ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "license": "Unlicense" }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", @@ -13306,20 +11514,6 @@ "node": ">=8" } }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/unbash": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/unbash/-/unbash-4.0.7.tgz", @@ -13345,9 +11539,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/unicorn-magic": { @@ -13382,44 +11576,6 @@ "node": ">= 0.8" } }, - "node_modules/unrs-resolver": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", - "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.4" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.12.2", - "@unrs/resolver-binding-android-arm64": "1.12.2", - "@unrs/resolver-binding-darwin-arm64": "1.12.2", - "@unrs/resolver-binding-darwin-x64": "1.12.2", - "@unrs/resolver-binding-freebsd-x64": "1.12.2", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", - "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", - "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", - "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", - "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", - "@unrs/resolver-binding-linux-x64-musl": "1.12.2", - "@unrs/resolver-binding-openharmony-arm64": "1.12.2", - "@unrs/resolver-binding-wasm32-wasi": "1.12.2", - "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", - "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", - "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" - } - }, "node_modules/update-browserslist-db": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", @@ -13451,16 +11607,6 @@ "browserslist": ">= 4.21.0" } }, - "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": { - "punycode": "^2.1.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -13468,16 +11614,16 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", - "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", + "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/esm/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { @@ -13487,21 +11633,6 @@ "dev": true, "license": "MIT" }, - "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": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, "node_modules/validator": { "version": "13.15.35", "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", @@ -13520,6 +11651,218 @@ "node": ">= 0.8" } }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest-mock-extended": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/vitest-mock-extended/-/vitest-mock-extended-2.0.2.tgz", + "integrity": "sha512-n3MBqVITKyclZ0n0y66hkT4UiiEYFQn9tteAnIxT0MPz1Z8nFcPUG3Cf0cZOyoPOj/cq6Ab1XFw2lM/qM5EDWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-essentials": ">=10.0.0" + }, + "peerDependencies": { + "typescript": "3.x || 4.x || 5.x", + "vitest": ">=2.0.0" + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/vscode-languageserver-textdocument": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", @@ -13544,16 +11887,6 @@ "node": "20 || >=22" } }, - "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": { - "makeerror": "1.0.12" - } - }, "node_modules/watskeburt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-6.0.0.tgz", @@ -13574,20 +11907,13 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "engines": { + "node": ">= 8" } }, "node_modules/which": { @@ -13606,6 +11932,23 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wkx": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", @@ -13615,23 +11958,6 @@ "@types/node": "*" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/wordwrapjs": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", @@ -13748,20 +12074,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, - "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": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/ws": { "version": "8.21.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", @@ -13894,19 +12206,6 @@ "node": ">=6" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yoctocolors": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", diff --git a/package.json b/package.json index 82f0ac0..5e0e371 100644 --- a/package.json +++ b/package.json @@ -2,39 +2,26 @@ "name": "variamos-ms-admin", "version": "0.0.0", "private": true, + "type": "module", "scripts": { - "build": "npx ts-node build.ts", - "lint": "eslint src/", - "lint:diff": "git diff HEAD --name-only | grep -E '\\.(ts|js)$' | xargs -r npx eslint", - "lint:diff:fix": "git diff HEAD --name-only | grep -E '\\.(ts|js)$' | xargs -r npx eslint --fix", - "prettier:diff": "git diff HEAD --name-only | grep -E '\\.(ts|js|json|css|md)$' | xargs -r npx prettier --write", - "fix:all": "npm run prettier:diff && npm run lint:diff:fix", - "start": "node -r module-alias/register ./dist --env=production", - "dev": "nodemon", - "test": "jest", - "test:unit": "jest src/Domain", - "test:integration": "jest src/EntryPoints", - "test:coverage": "jest --coverage", + "build": "npx tsx build.ts", + "lint": "biome check src/", + "lint:diff": "biome check --changed src/", + "lint:diff:fix": "biome check --write --changed src/", + "fix:all": "biome check --write src/", + "start": "node ./dist/index.js --env=production", + "dev": "npx tsx watch src/index.ts", + "test": "vitest run", + "test:unit": "vitest run src/Domain", + "test:integration": "vitest run src/EntryPoints", + "test:coverage": "vitest run --coverage", "stryker:domain": "stryker run stryker.domain.config.json", "stryker:entrypoints": "stryker run stryker.entrypoints.config.json", "prepare": "husky", - "check-arch": "dependency-cruiser --config .dependency-cruiser.js src/", + "check-arch": "dependency-cruiser --config .dependency-cruiser.cjs src/", "typecheck": "tsc --noEmit", "find-deadcode": "knip" }, - "nodemonConfig": { - "watch": [ - "src" - ], - "ext": "ts, html", - "ignore": [ - "src/public" - ], - "exec": "./node_modules/.bin/ts-node --files -r tsconfig-paths/register ./src" - }, - "_moduleAliases": { - "@src": "dist" - }, "engines": { "node": ">=24.0.0" }, @@ -42,15 +29,15 @@ "@variamosple/variamos-security": "^0.0.15", "axios": "^1.7.7", "bcrypt": "^6.0.0", - "cookie": "^1.0.2", + "cookie": "^2.0.1", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "dockerode": "^5.0.1", "dotenv": "^17.4.2", "express": "^5.2.1", - "google-auth-library": "^9.14.1", - "helmet": "^7.1.0", - "jet-logger": "^1.3.1", + "google-auth-library": "^11.0.0", + "helmet": "^8.3.0", + "jet-logger": "^2.2.3", "module-alias": "^2.2.3", "morgan": "^1.11.0", "multer": "^2.1.1", @@ -58,16 +45,16 @@ "pg": "^8.22.0", "sequelize": "^6.37.8", "ts-command-line-args": "^2.5.1", - "uuid": "^11.1.1", + "uuid": "^14.0.1", "ws": "^8.21.1" }, "devDependencies": { - "@commitlint/cli": "^20.5.3", - "@commitlint/config-conventional": "^20.5.3", + "@commitlint/cli": "^21.0.0", + "@commitlint/config-conventional": "^21.0.0", "@stryker-mutator/core": "^9.6.1", - "@stryker-mutator/jest-runner": "^9.6.1", "@stryker-mutator/typescript-checker": "^9.6.1", - "@types/bcrypt": "^5.0.2", + "@stryker-mutator/vitest-runner": "^9.6.1", + "@types/bcrypt": "^6.0.0", "@types/cookie-parser": "^1.4.7", "@types/cors": "^2.8.17", "@types/dockerode": "^4.0.1", @@ -76,35 +63,31 @@ "@types/jest": "^30.0.0", "@types/morgan": "^1.9.9", "@types/multer": "^2.1.0", - "@types/node": "^22.5.0", + "@types/node": "^24.0.0", "@types/nodemailer": "^8.0.0", "@types/supertest": "^7.2.0", "@types/ws": "^8.18.1", - "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", - "cspell": "^9.8.0", + "@vitest/coverage-v8": "^3.0.5", + "@biomejs/biome": "^1.9.4", + "cspell": "^10.0.1", "dependency-cruiser": "^18.1.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.5.6", "fs-extra": "^11.4.0", "husky": "^9.1.7", - "jest": "^30.4.2", - "jest-mock-extended": "^4.0.1", + "vitest-mock-extended": "^2.0.1", "knip": "^6.24.0", "lint-staged": "^17.3.0", "nodemon": "^3.1.14", - "prettier": "^3.9.6", "supertest": "^7.2.2", - "ts-jest": "^29.4.11", "ts-node": "^10.9.2", + "tsc-alias": "^1.8.10", "tsconfig-paths": "^4.2.0", - "typescript": "^5.5.4" + "tsx": "^4.19.2", + "typescript": "^5.8.2", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" }, "overrides": { - "uuid": "^11.1.1", + "uuid": "^14.0.1", "qs": "^6.15.2" }, "allowScripts": { @@ -112,6 +95,8 @@ "cpu-features@0.0.10": true, "protobufjs@7.6.5": true, "ssh2@1.17.0": true, - "unrs-resolver@1.12.2": true + "unrs-resolver@1.12.2": true, + "esbuild@0.28.1": true, + "@biomejs/biome@1.9.4": true } } diff --git a/src/CompositionRoot.ts b/src/CompositionRoot.ts index 4a0f256..05605a5 100644 --- a/src/CompositionRoot.ts +++ b/src/CompositionRoot.ts @@ -1,46 +1,46 @@ -import EnvVars from "@src/common/EnvVars"; -import { UserRepositoryImpl } from "./DataProviders/User/UserRepository"; -import { MicroServiceRepositoryImpl } from "./DataProviders/MicroService/MicroServiceRepository"; -import { RoleRepositoryImpl } from "./DataProviders/Role/RoleRepository"; -import { RolePermissionRepositoryImpl } from "./DataProviders/Role/RolePermissionRepository"; -import { UserRoleRepositoryImpl } from "./DataProviders/User/UserRoleRepository"; -import { PermissionRepositoryImpl } from "./DataProviders/Permission/PermissionRepository"; -import { VisitRepositoryImpl } from "./DataProviders/Visit/VisitRepository"; -import { CountriesRepositoryImpl } from "./DataProviders/Countries/CountriesRepository"; -import { MetricsRepositoryImpl } from "./DataProviders/Metrics/MetricsRepository"; -import { BugRepositoryImpl } from "./DataProviders/Bug/BugRepository"; +import EnvVars from "@src/common/EnvVars.js"; +import { BugRepositoryImpl } from "./DataProviders/Bug/BugRepository.js"; +import { CountriesRepositoryImpl } from "./DataProviders/Countries/CountriesRepository.js"; +import { MetricsRepositoryImpl } from "./DataProviders/Metrics/MetricsRepository.js"; +import { MicroServiceRepositoryImpl } from "./DataProviders/MicroService/MicroServiceRepository.js"; +import { PermissionRepositoryImpl } from "./DataProviders/Permission/PermissionRepository.js"; +import { RolePermissionRepositoryImpl } from "./DataProviders/Role/RolePermissionRepository.js"; +import { RoleRepositoryImpl } from "./DataProviders/Role/RoleRepository.js"; +import { UserRepositoryImpl } from "./DataProviders/User/UserRepository.js"; +import { UserRoleRepositoryImpl } from "./DataProviders/User/UserRoleRepository.js"; +import { VisitRepositoryImpl } from "./DataProviders/Visit/VisitRepository.js"; // User Use Cases -import { UserAuthUseCase } from "./Domain/User/UseCase/UserAuthUseCase"; -import { UserPasswordUseCase } from "./Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "./Domain/User/UseCase/UserManagementUseCase"; -import { UserQueryUseCase } from "./Domain/User/UseCase/UserQueryUseCase"; -import { UserRoleUseCase } from "./Domain/User/UseCase/UserRoleUseCase"; +import { UserAuthUseCase } from "./Domain/User/UseCase/UserAuthUseCase.js"; +import { UserManagementUseCase } from "./Domain/User/UseCase/UserManagementUseCase.js"; +import { UserPasswordUseCase } from "./Domain/User/UseCase/UserPasswordUseCase.js"; +import { UserQueryUseCase } from "./Domain/User/UseCase/UserQueryUseCase.js"; +import { UserRoleUseCase } from "./Domain/User/UseCase/UserRoleUseCase.js"; // Bug Use Cases -import { GitHubTokenResolver } from "./Domain/Bug/Service/GitHubTokenResolver"; -import { BugSubmissionUseCase } from "./Domain/Bug/UseCase/BugSubmissionUseCase"; -import { BugLifecycleUseCase } from "./Domain/Bug/UseCase/BugLifecycleUseCase"; -import { BugSyncUseCase } from "./Domain/Bug/UseCase/BugSyncUseCase"; -import { BugQueryUseCase } from "./Domain/Bug/UseCase/BugQueryUseCase"; -import { BugAttachmentUseCase } from "./Domain/Bug/UseCase/BugAttachmentUseCase"; +import { GitHubTokenResolver } from "./Domain/Bug/Service/GitHubTokenResolver.js"; +import { BugAttachmentUseCase } from "./Domain/Bug/UseCase/BugAttachmentUseCase.js"; +import { BugLifecycleUseCase } from "./Domain/Bug/UseCase/BugLifecycleUseCase.js"; +import { BugQueryUseCase } from "./Domain/Bug/UseCase/BugQueryUseCase.js"; +import { BugSubmissionUseCase } from "./Domain/Bug/UseCase/BugSubmissionUseCase.js"; +import { BugSyncUseCase } from "./Domain/Bug/UseCase/BugSyncUseCase.js"; // Permission & Role Use Cases -import { PermissionUseCase } from "./Domain/Permission/UseCase/PermissionUseCase"; -import { RoleManagementUseCase } from "./Domain/Role/UseCase/RoleManagementUseCase"; -import { RoleQueryUseCase } from "./Domain/Role/UseCase/RoleQueryUseCase"; -import { RolePermissionUseCase } from "./Domain/Role/UseCase/RolePermissionUseCase"; +import { PermissionUseCase } from "./Domain/Permission/UseCase/PermissionUseCase.js"; +import { RoleManagementUseCase } from "./Domain/Role/UseCase/RoleManagementUseCase.js"; +import { RolePermissionUseCase } from "./Domain/Role/UseCase/RolePermissionUseCase.js"; +import { RoleQueryUseCase } from "./Domain/Role/UseCase/RoleQueryUseCase.js"; +import { CountriesQueryUseCase } from "./Domain/Countries/UseCase/CountriesQueryUseCase.js"; // Other Use Cases -import { MetricsQueryUseCase } from "./Domain/Metrics/UseCase/MetricsQueryUseCase"; -import { VisitUseCase } from "./Domain/Visit/UseCase/VisitUseCase"; -import { CountriesQueryUseCase } from "./Domain/Countries/UseCase/CountriesQueryUseCase"; -import { MicroServiceQueryUseCase } from "./Domain/MicroService/UseCase/MicroServiceQueryUseCase"; -import { MicroServiceManagementUseCase } from "./Domain/MicroService/UseCase/MicroServiceManagementUseCase"; +import { MetricsQueryUseCase } from "./Domain/Metrics/UseCase/MetricsQueryUseCase.js"; +import { MicroServiceManagementUseCase } from "./Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; +import { MicroServiceQueryUseCase } from "./Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +import { VisitUseCase } from "./Domain/Visit/UseCase/VisitUseCase.js"; -import { MailServiceInstance } from "./Infrastructure/Mail/MailService"; -import { GitHubIssuesServiceInstance } from "./Infrastructure/GitHub/GitHubIssuesService"; -import { DiskStorageServiceInstance } from "./Infrastructure/Storage/DiskStorageService"; +import { GitHubIssuesServiceInstance } from "./Infrastructure/GitHub/GitHubIssuesService.js"; +import { MailServiceInstance } from "./Infrastructure/Mail/MailService.js"; +import { DiskStorageServiceInstance } from "./Infrastructure/Storage/DiskStorageService.js"; // Repositories export const UserRepositoryInstance = new UserRepositoryImpl({ @@ -52,7 +52,8 @@ export const MicroServiceRepositoryInstance = new MicroServiceRepositoryImpl({ }); export const RoleRepositoryInstance = new RoleRepositoryImpl(); -export const RolePermissionRepositoryInstance = new RolePermissionRepositoryImpl(); +export const RolePermissionRepositoryInstance = + new RolePermissionRepositoryImpl(); export const UserRoleRepositoryInstance = new UserRoleRepositoryImpl(); export const PermissionRepositoryInstance = new PermissionRepositoryImpl(); export const VisitRepositoryInstance = new VisitRepositoryImpl(); @@ -75,11 +76,17 @@ export const productionUserPasswordUseCase = new UserPasswordUseCase( }, ); -export const productionUserManagementUseCase = new UserManagementUseCase(UserRepositoryInstance); +export const productionUserManagementUseCase = new UserManagementUseCase( + UserRepositoryInstance, +); -export const productionUserQueryUseCase = new UserQueryUseCase(UserRepositoryInstance); +export const productionUserQueryUseCase = new UserQueryUseCase( + UserRepositoryInstance, +); -export const productionUserRoleUseCase = new UserRoleUseCase(UserRoleRepositoryInstance); +export const productionUserRoleUseCase = new UserRoleUseCase( + UserRoleRepositoryInstance, +); // Bug Tracker Config const bugTrackerConfig = { @@ -91,7 +98,9 @@ const bugTrackerConfig = { }; // GitHub Token Resolver -export const productionGitHubTokenResolver = new GitHubTokenResolver(bugTrackerConfig); +export const productionGitHubTokenResolver = new GitHubTokenResolver( + bugTrackerConfig, +); // Bug Use Case Instantiations export const productionBugSubmissionUseCase = new BugSubmissionUseCase( @@ -128,17 +137,25 @@ export const productionBugAttachmentUseCase = new BugAttachmentUseCase( ); // Other Use Case Instantiations -export const productionPermissionUseCase = new PermissionUseCase(PermissionRepositoryInstance); +export const productionPermissionUseCase = new PermissionUseCase( + PermissionRepositoryInstance, +); -export const productionRoleManagementUseCase = new RoleManagementUseCase(RoleRepositoryInstance); +export const productionRoleManagementUseCase = new RoleManagementUseCase( + RoleRepositoryInstance, +); -export const productionRoleQueryUseCase = new RoleQueryUseCase(RoleRepositoryInstance); +export const productionRoleQueryUseCase = new RoleQueryUseCase( + RoleRepositoryInstance, +); export const productionRolePermissionUseCase = new RolePermissionUseCase( RolePermissionRepositoryInstance, ); -export const productionMetricsQueryUseCase = new MetricsQueryUseCase(MetricsRepositoryInstance); +export const productionMetricsQueryUseCase = new MetricsQueryUseCase( + MetricsRepositoryInstance, +); export const productionVisitUseCase = new VisitUseCase( VisitRepositoryInstance, @@ -153,6 +170,5 @@ export const productionMicroServiceQueryUseCase = new MicroServiceQueryUseCase( MicroServiceRepositoryInstance, ); -export const productionMicroServiceManagementUseCase = new MicroServiceManagementUseCase( - MicroServiceRepositoryInstance, -); +export const productionMicroServiceManagementUseCase = + new MicroServiceManagementUseCase(MicroServiceRepositoryInstance); diff --git a/src/DataProviders/BaseRepository.ts b/src/DataProviders/BaseRepository.ts index 9ed6b3b..131d7fd 100644 --- a/src/DataProviders/BaseRepository.ts +++ b/src/DataProviders/BaseRepository.ts @@ -1,6 +1,5 @@ -/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/explicit-member-accessibility */ export interface Replacements { - [key: string]: any; + [key: string]: string | number | boolean | null | Date | string[] | number[]; } export abstract class BaseRepository { @@ -9,10 +8,13 @@ export abstract class BaseRepository { return {}; } - return Object.entries(filter).reduce((result, [key, value]) => { - result[key] = value === undefined ? null : value; + return Object.entries(filter).reduce( + (result, [key, value]) => { + result[key] = value === undefined ? null : value; - return result; - }, {}); + return result; + }, + {}, + ); } } diff --git a/src/DataProviders/Bug/Bug.ts b/src/DataProviders/Bug/Bug.ts index 3ae62f1..58c4c0d 100644 --- a/src/DataProviders/Bug/Bug.ts +++ b/src/DataProviders/Bug/Bug.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { DATE, ENUM, INTEGER, Model, TEXT, UUID, UUIDV4 } from "sequelize"; export interface BugAttributes { diff --git a/src/DataProviders/Bug/BugAssociations.ts b/src/DataProviders/Bug/BugAssociations.ts index 0215297..39046c0 100644 --- a/src/DataProviders/Bug/BugAssociations.ts +++ b/src/DataProviders/Bug/BugAssociations.ts @@ -1,7 +1,7 @@ -import { BugModel } from "./Bug"; -import { BugAttachmentModel } from "./BugAttachment"; -import { BugLogModel } from "./BugLog"; -import { UserModel } from "../User/User"; +import { UserModel } from "../User/User.js"; +import { BugModel } from "./Bug.js"; +import { BugAttachmentModel } from "./BugAttachment.js"; +import { BugLogModel } from "./BugLog.js"; // Bug Associations BugModel.hasMany(BugAttachmentModel, { @@ -36,7 +36,7 @@ BugLogModel.belongsTo(UserModel, { as: "changedBy", }); -import { BugNoteModel } from "./BugNote"; +import { BugNoteModel } from "./BugNote.js"; BugModel.hasMany(BugNoteModel, { foreignKey: "bug_id", diff --git a/src/DataProviders/Bug/BugAttachment.ts b/src/DataProviders/Bug/BugAttachment.ts index e2503d5..98a2f36 100644 --- a/src/DataProviders/Bug/BugAttachment.ts +++ b/src/DataProviders/Bug/BugAttachment.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { DATE, INTEGER, Model, TEXT, UUID } from "sequelize"; export interface BugAttachmentAttributes { diff --git a/src/DataProviders/Bug/BugLog.ts b/src/DataProviders/Bug/BugLog.ts index 42bd0c4..3df67be 100644 --- a/src/DataProviders/Bug/BugLog.ts +++ b/src/DataProviders/Bug/BugLog.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { DATE, INTEGER, Model, TEXT, UUID } from "sequelize"; export interface BugLogAttributes { @@ -11,7 +11,10 @@ export interface BugLogAttributes { updatedAt?: Date; } -export class BugLogModel extends Model implements BugLogAttributes { +export class BugLogModel + extends Model + implements BugLogAttributes +{ public id?: number; public action!: string; public comment?: string; diff --git a/src/DataProviders/Bug/BugNote.ts b/src/DataProviders/Bug/BugNote.ts index 4cadcbf..5d5ceb0 100644 --- a/src/DataProviders/Bug/BugNote.ts +++ b/src/DataProviders/Bug/BugNote.ts @@ -1,6 +1,6 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { DATE, INTEGER, Model, TEXT, UUID } from "sequelize"; -import { UserModel } from "../User/User"; +import { UserModel } from "../User/User.js"; export interface BugNoteAttributes { id?: number; @@ -10,7 +10,10 @@ export interface BugNoteAttributes { createdAt?: Date; } -export class BugNoteModel extends Model implements BugNoteAttributes { +export class BugNoteModel + extends Model + implements BugNoteAttributes +{ public id?: number; public body!: string; public bugId!: string; diff --git a/src/DataProviders/Bug/BugRepository.ts b/src/DataProviders/Bug/BugRepository.ts index 6ccecff..53944c2 100644 --- a/src/DataProviders/Bug/BugRepository.ts +++ b/src/DataProviders/Bug/BugRepository.ts @@ -1,20 +1,20 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog"; -import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter"; -import { BugModel } from "./Bug"; -import { BugAttachmentModel } from "./BugAttachment"; -import { BugLogModel } from "./BugLog"; -import { BugNoteModel } from "./BugNote"; -import { UserModel } from "../User/User"; -import { Op, Transaction, WhereOptions } from "sequelize"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment.js"; +import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter.js"; +import { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import VARIAMOS_ORM from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import VARIAMOS_ORM from "@src/Infrastructure/VariamosORM"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; -import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment"; +import { Op, type Transaction, type WhereOptions } from "sequelize"; +import { UserModel } from "../User/User.js"; +import { BugModel } from "./Bug.js"; +import { BugAttachmentModel } from "./BugAttachment.js"; +import { BugLogModel } from "./BugLog.js"; +import { BugNoteModel } from "./BugNote.js"; interface DbBugAttachment { id?: number; @@ -46,13 +46,22 @@ interface DbBugNoteWithAssociations extends BugNoteModel { } export class BugRepositoryImpl implements IBugRepository { - public async queryBugs(request: RequestModel): Promise> { + public async queryBugs( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const filter = request.data || new BugFilter(); const whereClause: Record< string | symbol, - string | number | boolean | object | null | undefined | string[] | object[] + | string + | number + | boolean + | object + | null + | undefined + | string[] + | object[] > = { githubRepo: { [Op.ne]: null }, gitIssueNumber: { [Op.ne]: null }, @@ -71,7 +80,7 @@ export class BugRepositoryImpl implements IBugRepository { ]; const numericSearch = Number(filter.search); - if (!isNaN(numericSearch)) { + if (!Number.isNaN(numericSearch)) { orConditions.push({ gitIssueNumber: numericSearch }); } @@ -125,13 +134,22 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async queryLocalBugs(request: RequestModel): Promise> { + public async queryLocalBugs( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const filter = request.data || new BugFilter(); const whereClause: Record< string | symbol, - string | number | boolean | object | null | undefined | string[] | object[] + | string + | number + | boolean + | object + | null + | undefined + | string[] + | object[] > = { reporterEmail: { [Op.ne]: null }, }; @@ -196,12 +214,17 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async findById(request: RequestModel): Promise> { + public async findById( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const id = request.data; if (!id) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Bug ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Bug ID is required.", + ); } const dbBug = await BugModel.findByPk(id, { include: [ @@ -256,7 +279,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const bug = request.data; if (!bug) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Bug data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Bug data is required.", + ); } const dbBug = await BugModel.findOne({ where: { @@ -314,7 +340,9 @@ export class BugRepositoryImpl implements IBugRepository { dbBug.githubAssignee = bug.githubAssignee; changed = true; } - if (dbBug.githubCreatedAt?.toISOString() !== bug.createdAt?.toISOString()) { + if ( + dbBug.githubCreatedAt?.toISOString() !== bug.createdAt?.toISOString() + ) { dbBug.githubCreatedAt = bug.createdAt; changed = true; } @@ -341,14 +369,20 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } const { id, adminId, logComment } = data; await VARIAMOS_ORM.transaction(async (t) => { const dbBug = await BugModel.findByPk(id, { transaction: t }); if (!dbBug) { - response.withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Local bug not found"); + response.withError( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Local bug not found", + ); return; } @@ -367,7 +401,10 @@ export class BugRepositoryImpl implements IBugRepository { { transaction: t }, ); - response.data = Bug.builder().setId(dbBug.id).setStatus(dbBug.status).build(); + response.data = Bug.builder() + .setId(dbBug.id) + .setStatus(dbBug.status) + .build(); }); } catch (error) { const err = error as Error; @@ -384,14 +421,20 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } const { id, adminId, logComment } = data; await VARIAMOS_ORM.transaction(async (t) => { const dbBug = await BugModel.findByPk(id, { transaction: t }); if (!dbBug) { - response.withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Local bug not found"); + response.withError( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Local bug not found", + ); return; } @@ -410,7 +453,10 @@ export class BugRepositoryImpl implements IBugRepository { { transaction: t }, ); - response.data = Bug.builder().setId(dbBug.id).setStatus(dbBug.status).build(); + response.data = Bug.builder() + .setId(dbBug.id) + .setStatus(dbBug.status) + .build(); }); } catch (error) { const err = error as Error; @@ -420,12 +466,17 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async findExpiredRejectedBugs(request: RequestModel): Promise> { + public async findExpiredRejectedBugs( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const thresholdDate = request.data; if (!thresholdDate) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Threshold date is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Threshold date is required.", + ); } const dbBugs = await BugModel.findAll({ where: { @@ -468,7 +519,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } const { id, filePath } = data; await BugAttachmentModel.update({ filePath }, { where: { id } }); @@ -492,7 +546,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Log data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Log data is required.", + ); } const { action, comment, bugId, operatorId } = data; await BugLogModel.create({ @@ -529,7 +586,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } const { title, @@ -628,12 +688,17 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async queryHistory(request: RequestModel): Promise> { + public async queryHistory( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const bugId = request.data; if (!bugId) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Bug ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Bug ID is required.", + ); } const logs = await BugLogModel.findAll({ where: { bugId }, @@ -686,7 +751,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } const { id, @@ -704,7 +772,10 @@ export class BugRepositoryImpl implements IBugRepository { await VARIAMOS_ORM.transaction(async (t) => { const dbBug = await BugModel.findByPk(id, { transaction: t }); if (!dbBug) { - response.withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Bug not found"); + response.withError( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Bug not found", + ); return; } @@ -744,7 +815,10 @@ export class BugRepositoryImpl implements IBugRepository { { transaction: t }, ); - response.data = Bug.builder().setId(dbBug.id).setStatus(dbBug.status).build(); + response.data = Bug.builder() + .setId(dbBug.id) + .setStatus(dbBug.status) + .build(); }); } catch (error) { const err = error as Error; @@ -765,7 +839,10 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Attachment data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Attachment data is required.", + ); } const { filePath, fileType, bugId } = data; const attachment = await BugAttachmentModel.create({ @@ -787,12 +864,17 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async deleteAttachment(request: RequestModel): Promise> { + public async deleteAttachment( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const id = request.data; if (!id) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Attachment ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Attachment ID is required.", + ); } await BugAttachmentModel.destroy({ where: { id } }); } catch (error) { @@ -806,11 +888,16 @@ export class BugRepositoryImpl implements IBugRepository { public async findAttachmentById( request: RequestModel, ): Promise> { - const response = new ResponseModel(request.transactionId); + const response = new ResponseModel( + request.transactionId, + ); try { const id = request.data; if (!id) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Attachment ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Attachment ID is required.", + ); } const attachment = await BugAttachmentModel.findByPk(id); response.data = attachment @@ -845,12 +932,17 @@ export class BugRepositoryImpl implements IBugRepository { try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Note data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Note data is required.", + ); } const { bugId, body, authorId } = data; // Prevent FK violation by ensuring authorId exists in local user table - const resolvedAuthorId = authorId ? await this.resolveOperatorId(authorId) : undefined; + const resolvedAuthorId = authorId + ? await this.resolveOperatorId(authorId) + : undefined; const dbNote = await BugNoteModel.create({ bugId, @@ -880,12 +972,17 @@ export class BugRepositoryImpl implements IBugRepository { return response; } - public async queryNotes(request: RequestModel): Promise> { + public async queryNotes( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const bugId = request.data; if (!bugId) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Bug ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Bug ID is required.", + ); } const dbNotes = await BugNoteModel.findAll({ where: { bugId }, diff --git a/src/DataProviders/Countries/CountriesRepository.ts b/src/DataProviders/Countries/CountriesRepository.ts index 94dfa4d..2e75ee5 100644 --- a/src/DataProviders/Countries/CountriesRepository.ts +++ b/src/DataProviders/Countries/CountriesRepository.ts @@ -1,16 +1,21 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; -import { Country } from "@src/Domain/Countries/Entity/Country"; +import { Country } from "@src/Domain/Countries/Entity/Country.js"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; import logger from "jet-logger"; -import { BaseRepository } from "../BaseRepository"; -import { UserModel } from "../User/User"; -import { CountryModel } from "./Country"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; +import { BaseRepository } from "../BaseRepository.js"; +import { UserModel } from "../User/User.js"; +import { CountryModel } from "./Country.js"; -export class CountriesRepositoryImpl extends BaseRepository implements ICountriesRepository { - public async getCountries(request: RequestModel): Promise> { +export class CountriesRepositoryImpl + extends BaseRepository + implements ICountriesRepository +{ + public async getCountries( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -30,7 +35,10 @@ export class CountriesRepositoryImpl extends BaseRepository implements ICountrie logger.err("Error in getCountries:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -40,13 +48,18 @@ export class CountriesRepositoryImpl extends BaseRepository implements ICountrie const response = new ResponseModel(request.transactionId); try { - response.data = await UserModel.findByPk(request.data).then((result) => result?.countryCode); + response.data = await UserModel.findByPk(request.data).then( + (result) => result?.countryCode, + ); } catch (error) { const err = error as Error; logger.err("Error in getUserCountryCode:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -54,11 +67,13 @@ export class CountriesRepositoryImpl extends BaseRepository implements ICountrie public async getIpCountryCode(request: RequestModel) { const response = new ResponseModel(request.transactionId); - logger.info("IP country code request for IP: " + request.data); + logger.info(`IP country code request for IP: ${request.data}`); await fetch(`https://api.ipquery.io/${request.data}`) .then((result) => { - return result.json() as Promise<{ location?: { country_code?: string } }>; + return result.json() as Promise<{ + location?: { country_code?: string }; + }>; }) .then((data) => { response.data = data?.location?.country_code; @@ -68,7 +83,10 @@ export class CountriesRepositoryImpl extends BaseRepository implements ICountrie logger.err("Error in getIpCountryCode:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); }); return response; diff --git a/src/DataProviders/Countries/Country.ts b/src/DataProviders/Countries/Country.ts index 1d52f34..2b8ed9a 100644 --- a/src/DataProviders/Countries/Country.ts +++ b/src/DataProviders/Countries/Country.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, NUMBER, TEXT } from "sequelize"; interface CountryAttributes { @@ -9,7 +9,10 @@ interface CountryAttributes { code3: string; } -export class CountryModel extends Model implements CountryAttributes { +export class CountryModel + extends Model + implements CountryAttributes +{ public code!: string; public name!: string; public latitude!: number; diff --git a/src/DataProviders/Metrics/MetricsRepository.ts b/src/DataProviders/Metrics/MetricsRepository.ts index becbac3..4196250 100644 --- a/src/DataProviders/Metrics/MetricsRepository.ts +++ b/src/DataProviders/Metrics/MetricsRepository.ts @@ -1,13 +1,13 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Metric } from "@src/Domain/Metrics/Entity/Metric"; -import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter"; -import { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository"; -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Metric } from "@src/Domain/Metrics/Entity/Metric.js"; +import type { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter.js"; +import type { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository.js"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; import { QueryTypes } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; +import { BaseRepository } from "../BaseRepository.js"; const METRICS_FUNCTIONS = new Map([ ["visitsByDay", `${DB_SCHEMA}.get_visits_by_day()`], @@ -21,7 +21,10 @@ const METRICS_FUNCTIONS = new Map([ ["errorRateBySystem", `${DB_SCHEMA}.get_error_rate_by_system()`], ]); -export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRepository { +export class MetricsRepositoryImpl + extends BaseRepository + implements IMetricsRepository +{ private metrics: Metric[] = []; public constructor() { @@ -33,9 +36,12 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep logger.info("Refreshing metrics..."); try { - this.metrics = await VARIAMOS_ORM.query(`SELECT ${DB_SCHEMA}.get_metrics() AS data`, { - type: QueryTypes.SELECT, - }).then(([result]: object[]) => { + this.metrics = await VARIAMOS_ORM.query( + `SELECT ${DB_SCHEMA}.get_metrics() AS data`, + { + type: QueryTypes.SELECT, + }, + ).then(([result]: object[]) => { const resObj = result as | { data?: { @@ -50,16 +56,17 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep } | undefined; if (!resObj || !resObj.data) return []; - return resObj.data.map(({ id, title, chartType, defaultFilter, filters, labelKey, data }) => - Metric.builder() - .setId(id) - .setTitle(title) - .setChartType(chartType) - .setDefaultFilter(defaultFilter) - .setFilters(filters) - .setLabelKey(labelKey) - .setData(data) - .build(), + return resObj.data.map( + ({ id, title, chartType, defaultFilter, filters, labelKey, data }) => + Metric.builder() + .setId(id) + .setTitle(title) + .setChartType(chartType) + .setDefaultFilter(defaultFilter) + .setFilters(filters) + .setLabelKey(labelKey) + .setData(data) + .build(), ); }); @@ -71,7 +78,9 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep } } - public getMetrics(request: RequestModel): Promise> { + public getMetrics( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -81,32 +90,46 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep logger.err("Error in getMetrics:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return Promise.resolve(response); } - public async queryMetric(request: RequestModel): Promise> { + public async queryMetric( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const data = request.data; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Metrics filter is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Metrics filter is required.", + ); } const replacements = this.initializeReplacements(data); const selectedFunction = METRICS_FUNCTIONS.get(String(replacements.id)); if (!selectedFunction) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Invalid metric id"); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Invalid metric id", + ); } - const result = await VARIAMOS_ORM.query(`SELECT ${selectedFunction} AS data`, { - type: QueryTypes.SELECT, - replacements, - }).then(([result]: object[]) => { + const result = await VARIAMOS_ORM.query( + `SELECT ${selectedFunction} AS data`, + { + type: QueryTypes.SELECT, + replacements, + }, + ).then(([result]: object[]) => { const resObj = result as | { data: { @@ -120,7 +143,8 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep }; } | undefined; - if (!resObj || !resObj.data) throw new Error("Invalid database response format"); + if (!resObj || !resObj.data) + throw new Error("Invalid database response format"); const { id, title, @@ -148,7 +172,10 @@ export class MetricsRepositoryImpl extends BaseRepository implements IMetricsRep logger.err("Error in queryMetric:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/MicroService/MicroServiceRepository.ts b/src/DataProviders/MicroService/MicroServiceRepository.ts index 0515b05..2e3c7df 100644 --- a/src/DataProviders/MicroService/MicroServiceRepository.ts +++ b/src/DataProviders/MicroService/MicroServiceRepository.ts @@ -1,13 +1,13 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroService } from "@src/Domain/MicroService/Entity/MicroService"; -import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { MicroService } from "@src/Domain/MicroService/Entity/MicroService.js"; +import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; import Docker from "dockerode"; import logger from "jet-logger"; -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; export class MicroServiceRepositoryImpl implements IMicroServiceRepository { private dockerConnection: Docker; @@ -35,7 +35,9 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { (container) => !filter.name || container.Names.findIndex((name) => - name.toLowerCase().includes(filter.name ? filter.name.toLowerCase() : ""), + name + .toLowerCase() + .includes(filter.name ? filter.name.toLowerCase() : ""), ) !== -1, ), ); @@ -66,27 +68,35 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in queryMicroServices:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async queryById(request: RequestModel): Promise> { + public async queryById( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: id } = request; if (!id) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Microservice ID is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Microservice ID is required", + ); return response; } const container = this.dockerConnection.getContainer(id); const containerInfo = await container.inspect(); - if (!!container) { + if (container) { response.data = MicroService.builder() .setId(container.id) .setNames([containerInfo.Name]) @@ -99,20 +109,28 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in queryMicroServiceById:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async startMicroService(request: RequestModel): Promise> { + public async startMicroService( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: id } = request; if (!id) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Microservice ID is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Microservice ID is required", + ); return response; } @@ -122,20 +140,28 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in startMicroService:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async stopMicroService(request: RequestModel): Promise> { + public async stopMicroService( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: id } = request; if (!id) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Microservice ID is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Microservice ID is required", + ); return response; } @@ -145,20 +171,28 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in stopMicroService:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async restartMicroService(request: RequestModel): Promise> { + public async restartMicroService( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: id } = request; if (!id) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Microservice ID is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Microservice ID is required", + ); return response; } @@ -168,7 +202,10 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in restartMicroService:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -177,13 +214,18 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { public async watchMicroServiceLogs( request: RequestModel, ): Promise> { - const response = new ResponseModel(request.transactionId); + const response = new ResponseModel( + request.transactionId, + ); try { const { data: id } = request; if (!id) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Microservice ID is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Microservice ID is required", + ); return response; } @@ -200,7 +242,10 @@ export class MicroServiceRepositoryImpl implements IMicroServiceRepository { logger.err("Error in watchMicroServiceLogs:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/Permission/Permission.ts b/src/DataProviders/Permission/Permission.ts index cc59864..92c10bf 100644 --- a/src/DataProviders/Permission/Permission.ts +++ b/src/DataProviders/Permission/Permission.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, NUMBER, TEXT } from "sequelize"; export interface PermissionAttributes { @@ -6,7 +6,10 @@ export interface PermissionAttributes { name: string; } -export class PermissionModel extends Model implements PermissionAttributes { +export class PermissionModel + extends Model + implements PermissionAttributes +{ public id?: number; public name!: string; } diff --git a/src/DataProviders/Permission/PermissionRepository.ts b/src/DataProviders/Permission/PermissionRepository.ts index fcd23b7..2ebb7ca 100644 --- a/src/DataProviders/Permission/PermissionRepository.ts +++ b/src/DataProviders/Permission/PermissionRepository.ts @@ -1,19 +1,22 @@ -/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return */ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter"; -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/explicit-member-accessibility */ +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; -import { Op, QueryTypes, WhereOptions } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; -import { RolePermissionModel } from "../Role/RolePermission"; -import { PermissionAttributes, PermissionModel } from "./Permission"; +import { Op, QueryTypes, type WhereOptions } from "sequelize"; +import { BaseRepository } from "../BaseRepository.js"; +import { RolePermissionModel } from "../Role/RolePermission.js"; +import { type PermissionAttributes, PermissionModel } from "./Permission.js"; -import { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository"; +import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; -export class PermissionRepositoryImpl extends BaseRepository implements IPermissionRepository { +export class PermissionRepositoryImpl + extends BaseRepository + implements IPermissionRepository +{ async queryPermissions( request: RequestModel, ): Promise> { @@ -31,7 +34,10 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss WHERE (:name IS NULL OR name ILIKE '%' || :name || '%'); `, { type: QueryTypes.SELECT, replacements }, - ).then((result: any) => +result?.[0]?.count || 0); + ).then((result) => { + const rows = result as Array<{ count: string | number }>; + return +rows[0]?.count || 0; + }); const where: WhereOptions = {}; @@ -48,25 +54,35 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss limit: pageSize, offset, order: [["name", "ASC"]], - }).then((response) => response.map(({ id, name }) => new Permission(id, name))); + }).then((response) => + response.map(({ id, name }) => new Permission(id, name)), + ); } catch (error) { logger.err("Error in queryPermissions:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - async createPermission(request: RequestModel): Promise> { + async createPermission( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Permission data is required."); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Permission data is required.", + ); return response; } @@ -79,13 +95,18 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss logger.err("Error in createPermission:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - async deletePermission(request: RequestModel): Promise> { + async deletePermission( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -97,13 +118,18 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss logger.err("Error in deletePermission:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - async queryById(request: RequestModel): Promise> { + async queryById( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -111,25 +137,35 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss response.data = await PermissionModel.findOne({ where: { id: data }, - }).then((response) => (!response ? undefined : new Permission(response.id, response.name))); + }).then((response) => + !response ? undefined : new Permission(response.id, response.name), + ); } catch (error) { logger.err("Error in queryById:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - async updatePermission(request: RequestModel): Promise> { + async updatePermission( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data || data.id === undefined) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Permission data and ID are required."); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Permission data and ID are required.", + ); return response; } @@ -145,7 +181,10 @@ export class PermissionRepositoryImpl extends BaseRepository implements IPermiss logger.err("Error in updatePermission:"); logger.err(request); logger.err(error); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/Role/Role.ts b/src/DataProviders/Role/Role.ts index d5da08e..de27ce0 100644 --- a/src/DataProviders/Role/Role.ts +++ b/src/DataProviders/Role/Role.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, NUMBER, TEXT } from "sequelize"; export interface RoleAttributes { diff --git a/src/DataProviders/Role/RolePermission.ts b/src/DataProviders/Role/RolePermission.ts index ac1e21d..9f4b5fb 100644 --- a/src/DataProviders/Role/RolePermission.ts +++ b/src/DataProviders/Role/RolePermission.ts @@ -1,7 +1,7 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, NUMBER } from "sequelize"; -import { PermissionModel } from "../Permission/Permission"; -import { RoleModel } from "./Role"; +import { PermissionModel } from "../Permission/Permission.js"; +import { RoleModel } from "./Role.js"; interface RolePermissionAttributes { roleId: number; diff --git a/src/DataProviders/Role/RolePermissionRepository.ts b/src/DataProviders/Role/RolePermissionRepository.ts index 2347488..ee91552 100644 --- a/src/DataProviders/Role/RolePermissionRepository.ts +++ b/src/DataProviders/Role/RolePermissionRepository.ts @@ -1,16 +1,16 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { RolePermission } from "@src/Domain/Role/Entity/RolePermission"; -import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter"; -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; +import type { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter.js"; +import type { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository.js"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; import { QueryTypes } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; -import { PermissionModel } from "../Permission/Permission"; -import { RolePermissionModel } from "./RolePermission"; -import { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository"; +import { BaseRepository } from "../BaseRepository.js"; +import type { PermissionModel } from "../Permission/Permission.js"; +import { RolePermissionModel } from "./RolePermission.js"; export class RolePermissionRepositoryImpl extends BaseRepository @@ -64,7 +64,10 @@ export class RolePermissionRepositoryImpl logger.err("Error in queryRolePermissions:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -120,7 +123,10 @@ export class RolePermissionRepositoryImpl logger.err("Error in createRolePermission:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -159,11 +165,15 @@ export class RolePermissionRepositoryImpl logger.err("Error in deleteRolePermission:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } } -export const RolePermissionRepositoryInstance = new RolePermissionRepositoryImpl(); +export const RolePermissionRepositoryInstance = + new RolePermissionRepositoryImpl(); diff --git a/src/DataProviders/Role/RoleRepository.ts b/src/DataProviders/Role/RoleRepository.ts index 673210a..4579553 100644 --- a/src/DataProviders/Role/RoleRepository.ts +++ b/src/DataProviders/Role/RoleRepository.ts @@ -1,25 +1,27 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter"; -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; -import { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository"; -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter.js"; +import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; -import { Op, QueryTypes, WhereOptions } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; -import { PermissionModel } from "../Permission/Permission"; -import { UserRoleModel } from "../User/UserRole"; -import { RoleAttributes, RoleModel } from "./Role"; -import { RolePermissionModel } from "./RolePermission"; +import { Op, QueryTypes, type WhereOptions } from "sequelize"; +import { BaseRepository } from "../BaseRepository.js"; +import { PermissionModel } from "../Permission/Permission.js"; +import { UserRoleModel } from "../User/UserRole.js"; +import { type RoleAttributes, RoleModel } from "./Role.js"; +import { RolePermissionModel } from "./RolePermission.js"; export class RoleRepositoryImpl extends BaseRepository implements IRoleRepository, IGuestRoleRepository { - public async queryRoles(request: RequestModel): Promise> { + public async queryRoles( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -56,19 +58,27 @@ export class RoleRepositoryImpl logger.err("Error in getRoles:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async createRole(request: RequestModel): Promise> { + public async createRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Role data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Role data is required.", + ); } const newRole = await RoleModel.create({ @@ -81,19 +91,27 @@ export class RoleRepositoryImpl logger.err("Error in createRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async deleteRole(request: RequestModel): Promise> { + public async deleteRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: id } = request; if (!id) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Role ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Role ID is required.", + ); } const numericId = Number(id); @@ -106,19 +124,27 @@ export class RoleRepositoryImpl logger.err("Error in deleteRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async queryById(request: RequestModel): Promise> { + public async queryById( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Role ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Role ID is required.", + ); } const found = await RoleModel.findOne({ @@ -130,19 +156,27 @@ export class RoleRepositoryImpl logger.err("Error in queryById:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async updateRole(request: RequestModel): Promise> { + public async updateRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data || data.id === undefined || data.id === null) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Role data with ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Role data with ID is required.", + ); } await RoleModel.update( @@ -158,13 +192,18 @@ export class RoleRepositoryImpl logger.err("Error in updateRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async queryGuestRole(request: RequestModel): Promise> { + public async queryGuestRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -204,7 +243,10 @@ export class RoleRepositoryImpl logger.err("Error in queryGuestRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/User/User.ts b/src/DataProviders/User/User.ts index b97ce62..0a6778b 100644 --- a/src/DataProviders/User/User.ts +++ b/src/DataProviders/User/User.ts @@ -1,6 +1,6 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { BOOLEAN, DATE, Model, TEXT, UUID, UUIDV4 } from "sequelize"; -import { CountryModel } from "../Countries/Country"; +import { CountryModel } from "../Countries/Country.js"; export interface UserAttributes { id?: string; diff --git a/src/DataProviders/User/UserRepository.ts b/src/DataProviders/User/UserRepository.ts index 60fdeb1..979bcb3 100644 --- a/src/DataProviders/User/UserRepository.ts +++ b/src/DataProviders/User/UserRepository.ts @@ -1,29 +1,32 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { User } from "@src/Domain/User/Entity/User"; -import { UserFilter } from "@src/Domain/User/Entity/UserFilter"; -import { Credentials } from "@src/Domain/User/Entity/Credentials"; -import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration"; -import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate"; -import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; - -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; -import logger from "jet-logger"; -import { Op, QueryTypes, WhereOptions } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { Credentials } from "@src/Domain/User/Entity/Credentials.js"; +import type { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate.js"; +import type { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserFilter } from "@src/Domain/User/Entity/UserFilter.js"; +import type { UserRegistration } from "@src/Domain/User/Entity/UserRegistration.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; + +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import bcrypt from "bcrypt"; -import { RoleModel } from "../Role/Role"; -import { PermissionModel } from "../Permission/Permission"; -import { CountryModel } from "../Countries/Country"; -import { UserAttributes, UserModel } from "./User"; +import logger from "jet-logger"; +import { Op, QueryTypes, type WhereOptions } from "sequelize"; +import { BaseRepository } from "../BaseRepository.js"; +import { CountryModel } from "../Countries/Country.js"; +import type { PermissionModel } from "../Permission/Permission.js"; +import type { RoleModel } from "../Role/Role.js"; +import { type UserAttributes, UserModel } from "./User.js"; interface UserModelWithCountry extends UserModel { country?: CountryModel | null; } -export class UserRepositoryImpl extends BaseRepository implements IUserRepository { +export class UserRepositoryImpl + extends BaseRepository + implements IUserRepository +{ private readonly bcryptSaltRounds: number; public constructor(config: { bcryptSaltRounds: number }) { @@ -31,7 +34,9 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor this.bcryptSaltRounds = config.bcryptSaltRounds; } - public async queryUsers(request: RequestModel): Promise> { + public async queryUsers( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -55,7 +60,9 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor { name: { [Op.iLike]: `%${String(replacements.search)}%` } }, { email: { [Op.iLike]: `%${String(replacements.search)}%` } }, ], - ...(filter.name ? { name: { [Op.iLike]: `%${String(replacements.name)}%` } } : {}), + ...(filter.name + ? { name: { [Op.iLike]: `%${String(replacements.name)}%` } } + : {}), } : filter.name ? { name: { [Op.iLike]: `%${String(replacements.name)}%` } } @@ -70,17 +77,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor offset: (pageNumber - 1) * pageSize, order: [["name", "ASC"]], }).then((res) => - res.map(({ id, user, name, email, isEnabled, isDeleted, createdAt, lastLogin }) => - User.builder() - .setId(id) - .setUser(user) - .setName(name) - .setEmail(email) - .setIsEnabled(isEnabled ?? true) - .setIsDeleted(isDeleted ?? false) - .setCreatedAt(createdAt ?? new Date()) - .setLastLogin(lastLogin) - .build(), + res.map( + ({ + id, + user, + name, + email, + isEnabled, + isDeleted, + createdAt, + lastLogin, + }) => + User.builder() + .setId(id) + .setUser(user) + .setName(name) + .setEmail(email) + .setIsEnabled(isEnabled ?? true) + .setIsDeleted(isDeleted ?? false) + .setCreatedAt(createdAt ?? new Date()) + .setLastLogin(lastLogin) + .build(), ), ); } catch (error) { @@ -88,20 +105,28 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in getUsers:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async findSessionUser(request: RequestModel): Promise> { + public async findSessionUser( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: userId } = request; if (!userId) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "UserId is required"); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "UserId is required", + ); } const dbUser = await UserModel.findOne({ @@ -109,15 +134,24 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor }); if (!dbUser) { - return response.withError(DomainErrorCodes.ENTITY_NOT_FOUND, "User not found."); + return response.withError( + DomainErrorCodes.ENTITY_NOT_FOUND, + "User not found.", + ); } if (!dbUser.isEnabled) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Your account is disabled."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Your account is disabled.", + ); } if (dbUser.isDeleted) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Your account is deleted."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Your account is deleted.", + ); } response.data = User.builder() @@ -133,13 +167,18 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in findSessionUser:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async findOrCreateUser(request: RequestModel): Promise> { + public async findOrCreateUser( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -177,11 +216,17 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor }); if (!dbUser.isEnabled) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Your account is disabled."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Your account is disabled.", + ); } if (dbUser.isDeleted) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Your account is deleted."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Your account is deleted.", + ); } if (!crated) { @@ -208,19 +253,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in findOrCreateUser:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async signIn(request: RequestModel): Promise> { + public async signIn( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Credentials are required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Credentials are required.", + ); } const email = data.email; @@ -238,7 +291,12 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor const errorMessage = "Incorrect username or password."; - if (!dbUser || !dbUser.password || !dbUser.isEnabled || dbUser.isDeleted) { + if ( + !dbUser || + !dbUser.password || + !dbUser.isEnabled || + dbUser.isDeleted + ) { return response.withError(DomainErrorCodes.INVALID_INPUT, errorMessage); } @@ -270,13 +328,18 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in signIn:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async signUp(request: RequestModel): Promise> { + public async signUp( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { @@ -331,19 +394,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in signUp:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async queryById(request: RequestModel): Promise> { + public async queryById( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "User ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "User ID is required.", + ); } response.data = await UserModel.findOne({ @@ -375,19 +446,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in queryById:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async disableUser(request: RequestModel): Promise> { + public async disableUser( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "User ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "User ID is required.", + ); } await UserModel.update( @@ -403,19 +482,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in disableUser:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async enableUser(request: RequestModel): Promise> { + public async enableUser( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "User ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "User ID is required.", + ); } await UserModel.update( @@ -431,19 +518,27 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in enableUser:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async deleteUser(request: RequestModel): Promise> { + public async deleteUser( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "User ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "User ID is required.", + ); } await UserModel.update( @@ -459,7 +554,10 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in deleteUser:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -519,7 +617,10 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor }); if (!dbUser) { - return response.withError(DomainErrorCodes.ENTITY_NOT_FOUND, "User not found."); + return response.withError( + DomainErrorCodes.ENTITY_NOT_FOUND, + "User not found.", + ); } const passwordMatch = await bcrypt.compare( @@ -528,10 +629,16 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor ); if (!passwordMatch) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Current password is incorrect."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Current password is incorrect.", + ); } - const newHashedPassword = await bcrypt.hash(passwordUpdate.getNewPassword(), 10); + const newHashedPassword = await bcrypt.hash( + passwordUpdate.getNewPassword(), + 10, + ); await UserModel.update( { password: newHashedPassword }, @@ -545,11 +652,13 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor const err = error as Error; logger.err("Error in updateUserPassword:"); logger.err( - "Error trying to update user password with id: " + - (request.data ? request.data.getId() : ""), + `Error trying to update user password with id: ${request.data ? request.data.getId() : ""}`, ); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -574,7 +683,7 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor .setCreatedAt(dbUser.createdAt || new Date()) .build(); } catch (error) { - logger.err("Error in getUserByEmail: " + error); + logger.err(`Error in getUserByEmail: ${error}`); return null; } } @@ -601,7 +710,7 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor }, ); } catch (error) { - logger.err("Error in savePasswordResetToken: " + error); + logger.err(`Error in savePasswordResetToken: ${error}`); throw error; } } @@ -632,7 +741,7 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor ); return results.length > 0 ? results[0] : null; } catch (error) { - logger.err("Error in getPasswordResetToken: " + error); + logger.err(`Error in getPasswordResetToken: ${error}`); return null; } } @@ -653,13 +762,22 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor throw new Error("User not found."); } - const isSamePassword = await bcrypt.compare(passwordPlain, dbUser.password || ""); + const isSamePassword = await bcrypt.compare( + passwordPlain, + dbUser.password || "", + ); if (isSamePassword) { throw new Error("New password cannot be the same as the old password."); } - const passwordHash = await bcrypt.hash(passwordPlain, this.bcryptSaltRounds); - await UserModel.update({ password: passwordHash }, { where: { id: userId }, transaction }); + const passwordHash = await bcrypt.hash( + passwordPlain, + this.bcryptSaltRounds, + ); + await UserModel.update( + { password: passwordHash }, + { where: { id: userId }, transaction }, + ); await VARIAMOS_ORM.query( ` @@ -676,7 +794,7 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor await transaction.commit(); } catch (error) { await transaction.rollback(); - logger.err("Error in resetPasswordAndUpdateToken: " + error); + logger.err(`Error in resetPasswordAndUpdateToken: ${error}`); throw error; } } @@ -707,23 +825,30 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor const err = error as Error; logger.err("Error in updatePersonalInformation:"); logger.err( - "Error trying to update user information with id: " + - (request.data ? request.data.getUserId() : ""), + `Error trying to update user information with id: ${request.data ? request.data.getUserId() : ""}`, ); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async userExists(request: RequestModel): Promise> { + public async userExists( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data: userId } = request; if (!userId) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "User ID is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "User ID is required.", + ); } response.data = await UserModel.count({ @@ -734,7 +859,10 @@ export class UserRepositoryImpl extends BaseRepository implements IUserRepositor logger.err("Error in userExists:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/User/UserRole.ts b/src/DataProviders/User/UserRole.ts index a21cfdf..9da8a99 100644 --- a/src/DataProviders/User/UserRole.ts +++ b/src/DataProviders/User/UserRole.ts @@ -1,14 +1,17 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, NUMBER, TEXT } from "sequelize"; -import { RoleModel } from "../Role/Role"; -import { UserModel } from "./User"; +import { RoleModel } from "../Role/Role.js"; +import { UserModel } from "./User.js"; interface UserRoleAttributes { userId: string; roleId: number; } -export class UserRoleModel extends Model implements UserRoleAttributes { +export class UserRoleModel + extends Model + implements UserRoleAttributes +{ public userId!: string; public roleId!: number; } diff --git a/src/DataProviders/User/UserRoleRepository.ts b/src/DataProviders/User/UserRoleRepository.ts index 1813d6a..9c4d508 100644 --- a/src/DataProviders/User/UserRoleRepository.ts +++ b/src/DataProviders/User/UserRoleRepository.ts @@ -1,22 +1,25 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; - -import { UserRole } from "@src/Domain/User/Entity/UserRole"; -import { UserRoleFilter } from "@src/Domain/User/Entity/UserRoleFilter"; -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; + +import { UserRole } from "@src/Domain/User/Entity/UserRole.js"; +import type { UserRoleFilter } from "@src/Domain/User/Entity/UserRoleFilter.js"; +import type { IUserRoleRepository } from "@src/Domain/User/Repository/IUserRoleRepository.js"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; import { QueryTypes } from "sequelize"; -import { BaseRepository } from "../BaseRepository"; -import { PermissionModel } from "../Permission/Permission"; -import { RoleModel } from "../Role/Role"; -import { UserModel } from "./User"; -import { UserRoleModel } from "./UserRole"; -import { IUserRoleRepository } from "@src/Domain/User/Repository/IUserRoleRepository"; - -export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleRepository { +import { BaseRepository } from "../BaseRepository.js"; +import { PermissionModel } from "../Permission/Permission.js"; +import { RoleModel } from "../Role/Role.js"; +import { UserModel } from "./User.js"; +import { UserRoleModel } from "./UserRole.js"; + +export class UserRoleRepositoryImpl + extends BaseRepository + implements IUserRoleRepository +{ public async queryUserRoles( request: RequestModel, ): Promise> { @@ -47,7 +50,6 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR return countObj ? Number(countObj.count) : 0; }); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment response.data = await VARIAMOS_ORM.query( ` SELECT r.* @@ -66,7 +68,10 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR logger.err("Error in queryUserRoles:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; @@ -99,12 +104,16 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR attributes: ["id", "name"], }).then((roles) => roles.map((role) => { - const typedRole = role as RoleModel & { permissions?: PermissionModel[] }; + const typedRole = role as RoleModel & { + permissions?: PermissionModel[]; + }; return new Role( typedRole.id, typedRole.name, typedRole.permissions - ? typedRole.permissions.map(({ id, name }) => new Permission(id, name)) + ? typedRole.permissions.map( + ({ id, name }) => new Permission(id, name), + ) : undefined, ); }), @@ -114,19 +123,27 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR logger.err("Error in queryUserRolesDetails:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async createUserRole(request: RequestModel): Promise> { + public async createUserRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "UserRole data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "UserRole data is required.", + ); } const userId = data.userId; @@ -160,19 +177,27 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR logger.err("Error in createUserRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; } - public async deleteUserRole(request: RequestModel): Promise> { + public async deleteUserRole( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "UserRole data is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "UserRole data is required.", + ); } const userId = data.userId; @@ -192,7 +217,10 @@ export class UserRoleRepositoryImpl extends BaseRepository implements IUserRoleR logger.err("Error in deleteUserRole:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/DataProviders/Visit/Visit.ts b/src/DataProviders/Visit/Visit.ts index 4f23a5b..f15ae52 100644 --- a/src/DataProviders/Visit/Visit.ts +++ b/src/DataProviders/Visit/Visit.ts @@ -1,4 +1,4 @@ -import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM"; +import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import { Model, TEXT, UUIDV4 } from "sequelize"; export interface VisitAttributes { @@ -7,7 +7,10 @@ export interface VisitAttributes { countryCode?: string; } -export class VisitModel extends Model implements VisitAttributes { +export class VisitModel + extends Model + implements VisitAttributes +{ public pageId!: string; public userId!: string; public countryCode?: string; diff --git a/src/DataProviders/Visit/VisitRepository.ts b/src/DataProviders/Visit/VisitRepository.ts index 3ba02b5..7bd6681 100644 --- a/src/DataProviders/Visit/VisitRepository.ts +++ b/src/DataProviders/Visit/VisitRepository.ts @@ -1,21 +1,29 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Visit } from "@src/Domain/Visit/Entity/Visit"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; +import type { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository.js"; // wait, check if IVsitRepository has typo in original import import logger from "jet-logger"; -import { BaseRepository } from "../BaseRepository"; -import { VisitModel } from "./Visit"; -import { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository"; // wait, check if IVsitRepository has typo in original import +import { BaseRepository } from "../BaseRepository.js"; +import { VisitModel } from "./Visit.js"; -export class VisitRepositoryImpl extends BaseRepository implements IVisitRepository { - public async registerVisit(request: RequestModel): Promise> { +export class VisitRepositoryImpl + extends BaseRepository + implements IVisitRepository +{ + public async registerVisit( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const { data } = request; if (!data) { - response.withError(DomainErrorCodes.INVALID_INPUT, "Visit data is required"); + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Visit data is required", + ); return response; } @@ -31,7 +39,10 @@ export class VisitRepositoryImpl extends BaseRepository implements IVisitReposit logger.err("Error in registerVisit:"); logger.err(request); logger.err(err); - response.withError(DomainErrorCodes.SYSTEM_ERROR, "Internal server error"); + response.withError( + DomainErrorCodes.SYSTEM_ERROR, + "Internal server error", + ); } return response; diff --git a/src/Domain/Bug/Entity/Bug.spec.ts b/src/Domain/Bug/Entity/Bug.spec.ts index fe07f92..3360193 100644 --- a/src/Domain/Bug/Entity/Bug.spec.ts +++ b/src/Domain/Bug/Entity/Bug.spec.ts @@ -1,8 +1,10 @@ -import { Bug } from "./Bug"; +import { Bug } from "./Bug.js"; describe("Bug Entity", () => { it("should successfully build a Bug entity using the builder", () => { - const attachments = [{ id: 1, filePath: "/a.png", fileType: "image/png", bugId: "bug-123" }]; + const attachments = [ + { id: 1, filePath: "/a.png", fileType: "image/png", bugId: "bug-123" }, + ]; const assignedAdmins = [{ id: "admin-1", name: "Admin One" }]; const bug = Bug.builder() @@ -30,8 +32,12 @@ describe("Bug Entity", () => { }); it("should throw an error for empty title", () => { - expect(() => Bug.builder().setTitle("").build()).toThrow("Bug title cannot be empty."); - expect(() => Bug.builder().setTitle(" ").build()).toThrow("Bug title cannot be empty."); + expect(() => Bug.builder().setTitle("").build()).toThrow( + "Bug title cannot be empty.", + ); + expect(() => Bug.builder().setTitle(" ").build()).toThrow( + "Bug title cannot be empty.", + ); }); it("should throw an error for empty description", () => { @@ -52,7 +58,9 @@ describe("Bug Entity", () => { describe("creatorName getter", () => { it("should return the name of the creator if createdBy is defined", () => { - const bug = Bug.builder().setCreatedBy({ id: "user-123", name: "John Doe" }).build(); + const bug = Bug.builder() + .setCreatedBy({ id: "user-123", name: "John Doe" }) + .build(); expect(bug.creatorName).toBe("John Doe"); }); diff --git a/src/Domain/Bug/Entity/Bug.ts b/src/Domain/Bug/Entity/Bug.ts index bfaab74..2887ecf 100644 --- a/src/Domain/Bug/Entity/Bug.ts +++ b/src/Domain/Bug/Entity/Bug.ts @@ -1,5 +1,5 @@ -import { BugPriority } from "./BugPriority"; -import { BugAttachment } from "./BugAttachment"; +import type { BugAttachment } from "./BugAttachment.js"; +import { BugPriority } from "./BugPriority.js"; export interface BugUserRef { id: string; @@ -149,7 +149,10 @@ class BugBuilder { if (this.title !== undefined && (!this.title || this.title.trim() === "")) { throw new Error("Bug title cannot be empty."); } - if (this.description !== undefined && (!this.description || this.description.trim() === "")) { + if ( + this.description !== undefined && + (!this.description || this.description.trim() === "") + ) { throw new Error("Bug description cannot be empty."); } if (this.priority !== undefined) { diff --git a/src/Domain/Bug/Entity/BugNote.test.ts b/src/Domain/Bug/Entity/BugNote.test.ts index 869b6e0..21c0db1 100644 --- a/src/Domain/Bug/Entity/BugNote.test.ts +++ b/src/Domain/Bug/Entity/BugNote.test.ts @@ -1,4 +1,4 @@ -import { BugNote } from "./BugNote"; +import { BugNote } from "./BugNote.js"; describe("BugNote Entity - Unit Tests", () => { it("should successfully build a BugNote using builder", () => { diff --git a/src/Domain/Bug/Entity/BugPriority.spec.ts b/src/Domain/Bug/Entity/BugPriority.spec.ts index 0f32fa6..918e64f 100644 --- a/src/Domain/Bug/Entity/BugPriority.spec.ts +++ b/src/Domain/Bug/Entity/BugPriority.spec.ts @@ -1,4 +1,4 @@ -import { BugPriority } from "./BugPriority"; +import { BugPriority } from "./BugPriority.js"; describe("BugPriority Value Object", () => { it("should create a valid priority successfully", () => { diff --git a/src/Domain/Bug/Entity/BugPriority.ts b/src/Domain/Bug/Entity/BugPriority.ts index 385d89f..51c5014 100644 --- a/src/Domain/Bug/Entity/BugPriority.ts +++ b/src/Domain/Bug/Entity/BugPriority.ts @@ -4,7 +4,9 @@ export class BugPriority { public constructor(value: string) { if (!value || !BugPriority.VALID_PRIORITIES.includes(value.toLowerCase())) { - throw new Error("Bug priority must be either 'low', 'medium', or 'high'."); + throw new Error( + "Bug priority must be either 'low', 'medium', or 'high'.", + ); } this.value = value.toLowerCase() as "low" | "medium" | "high"; } diff --git a/src/Domain/Bug/Entity/BugStatusLog.test.ts b/src/Domain/Bug/Entity/BugStatusLog.test.ts index cb0ffd9..5707889 100644 --- a/src/Domain/Bug/Entity/BugStatusLog.test.ts +++ b/src/Domain/Bug/Entity/BugStatusLog.test.ts @@ -1,4 +1,4 @@ -import { BugStatusLog } from "./BugStatusLog"; +import { BugStatusLog } from "./BugStatusLog.js"; describe("BugStatusLog Entity - Unit Tests", () => { it("should successfully build a BugStatusLog using builder", () => { diff --git a/src/Domain/Bug/Repository/IBugRepository.ts b/src/Domain/Bug/Repository/IBugRepository.ts index ee0e2ef..89df0b4 100644 --- a/src/Domain/Bug/Repository/IBugRepository.ts +++ b/src/Domain/Bug/Repository/IBugRepository.ts @@ -1,15 +1,17 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "../Entity/Bug"; -import { BugFilter } from "../Entity/BugFilter"; -import { BugStatusLog } from "../Entity/BugStatusLog"; -import { BugNote } from "../Entity/BugNote"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Bug } from "../Entity/Bug.js"; +import type { BugFilter } from "../Entity/BugFilter.js"; +import type { BugNote } from "../Entity/BugNote.js"; +import type { BugStatusLog } from "../Entity/BugStatusLog.js"; -import { BugAttachment } from "../Entity/BugAttachment"; +import type { BugAttachment } from "../Entity/BugAttachment.js"; export interface IBugRepository { queryBugs(request: RequestModel): Promise>; - queryLocalBugs(request: RequestModel): Promise>; + queryLocalBugs( + request: RequestModel, + ): Promise>; findById(request: RequestModel): Promise>; saveOrUpdateBug( request: RequestModel, @@ -28,7 +30,9 @@ export interface IBugRepository { logComment: string; }>, ): Promise>; - findExpiredRejectedBugs(request: RequestModel): Promise>; + findExpiredRejectedBugs( + request: RequestModel, + ): Promise>; updateAttachmentPath( request: RequestModel<{ id: number; filePath: string }>, ): Promise>; @@ -54,7 +58,9 @@ export interface IBugRepository { logComment: string; }>, ): Promise>; - queryHistory(request: RequestModel): Promise>; + queryHistory( + request: RequestModel, + ): Promise>; updateStatus( request: RequestModel<{ id: string; @@ -78,7 +84,9 @@ export interface IBugRepository { }>, ): Promise>; deleteAttachment(request: RequestModel): Promise>; - findAttachmentById(request: RequestModel): Promise>; + findAttachmentById( + request: RequestModel, + ): Promise>; createNote( request: RequestModel<{ bugId: string; body: string; authorId?: string }>, ): Promise>; diff --git a/src/Domain/Bug/Repository/IUserRepository.ts b/src/Domain/Bug/Repository/IUserRepository.ts index d06fad6..138cb53 100644 --- a/src/Domain/Bug/Repository/IUserRepository.ts +++ b/src/Domain/Bug/Repository/IUserRepository.ts @@ -1,6 +1,8 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; export interface IUserRepository { - findSessionUser(request: RequestModel): Promise>; + findSessionUser( + request: RequestModel, + ): Promise>; } diff --git a/src/Domain/Bug/Service/GitHubTokenResolver.test.ts b/src/Domain/Bug/Service/GitHubTokenResolver.test.ts index 047e091..f4cc522 100644 --- a/src/Domain/Bug/Service/GitHubTokenResolver.test.ts +++ b/src/Domain/Bug/Service/GitHubTokenResolver.test.ts @@ -1,38 +1,43 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { GitHubTokenResolver } from "./GitHubTokenResolver"; -import { IBugTrackerConfig } from "../Config/IBugTrackerConfig"; +import crypto from "node:crypto"; import axios from "axios"; -import crypto from "crypto"; import logger from "jet-logger"; - -jest.mock("axios"); -jest.mock("jet-logger"); -jest.mock("crypto", () => { - const actual = jest.requireActual("crypto"); +import { type MockProxy, mock } from "vitest-mock-extended"; +import type { IBugTrackerConfig } from "../Config/IBugTrackerConfig.js"; +import { GitHubTokenResolver } from "./GitHubTokenResolver.js"; + +vi.mock("axios"); +vi.mock("jet-logger"); +vi.mock("crypto", async () => { + const actual = await vi.importActual("crypto"); + const mockCreateSign = vi.fn(); return { ...actual, - createSign: jest.fn(), + createSign: mockCreateSign, + default: { + ...actual.default, + createSign: mockCreateSign, + }, }; }); describe("GitHubTokenResolver - Unit Tests", () => { let resolver: GitHubTokenResolver; let mockConfig: MockProxy; - let mockSign: { update: jest.Mock; sign: jest.Mock }; - let dateSpy: jest.SpyInstance; + let mockSign: { update: vi.Mock; sign: vi.Mock }; + let dateSpy: vi.SpyInstance; const mockNow = 1711800000000; // Fixed timestamp: 1711800000 seconds beforeEach(() => { - jest.clearAllMocks(); - dateSpy = jest.spyOn(Date, "now").mockReturnValue(mockNow); + vi.clearAllMocks(); + dateSpy = vi.spyOn(Date, "now").mockReturnValue(mockNow); mockConfig = mock(); resolver = new GitHubTokenResolver(mockConfig); mockSign = { - update: jest.fn(), - sign: jest.fn().mockReturnValue("mock-signature"), + update: vi.fn(), + sign: vi.fn().mockReturnValue("mock-signature"), }; - (crypto.createSign as jest.Mock).mockReturnValue(mockSign); + (crypto.createSign as vi.Mock).mockReturnValue(mockSign); }); afterEach(() => { @@ -41,8 +46,8 @@ describe("GitHubTokenResolver - Unit Tests", () => { describe("resolveGitHubToken", () => { it("should return the cached token if it is valid and not close to expiry", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue("12345"); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("mock-key"); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue("12345"); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue("mock-key"); resolver.tokenCache.set("VariaMos/VariaMosAdmin", { token: "cached-token", @@ -55,14 +60,16 @@ describe("GitHubTokenResolver - Unit Tests", () => { }); it("should fetch new token using GitHub App JWT and update cache on miss", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue(" 12345 "); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue(" 12345 "); // Passing private key with \n to test replace logic and spaces to test trim - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(" mock\\nkey "); + mockConfig.getGitHubPrivateKey = vi + .fn() + .mockReturnValue(" mock\\nkey "); - (axios.get as jest.Mock).mockResolvedValue({ + (axios.get as vi.Mock).mockResolvedValue({ data: { id: 987 }, }); - (axios.post as jest.Mock).mockResolvedValue({ + (axios.post as vi.Mock).mockResolvedValue({ data: { token: "new-app-token", expires_at: new Date(Date.now() + 600000).toISOString(), @@ -92,7 +99,9 @@ describe("GitHubTokenResolver - Unit Tests", () => { const expectedJwt = `${expectedHeaderB64}.${expectedPayloadB64}.mock-signature`; // Verify sign.update was called with exact header and payload to kill SL mutant at line 77 - expect(mockSign.update).toHaveBeenCalledWith(`${expectedHeaderB64}.${expectedPayloadB64}`); + expect(mockSign.update).toHaveBeenCalledWith( + `${expectedHeaderB64}.${expectedPayloadB64}`, + ); // Verify sign.sign was called with formatted private key to kill SL mutant at line 78 expect(mockSign.sign).toHaveBeenCalledWith("mock\nkey", "base64url"); @@ -123,15 +132,17 @@ describe("GitHubTokenResolver - Unit Tests", () => { ); // Verify second call hits cache - (axios.get as jest.Mock).mockClear(); - const token2 = await resolver.resolveGitHubToken("VariaMos/VariaMosAdmin"); + (axios.get as vi.Mock).mockClear(); + const token2 = await resolver.resolveGitHubToken( + "VariaMos/VariaMosAdmin", + ); expect(token2).toBe("new-app-token"); expect(axios.get).not.toHaveBeenCalled(); }); it("should fetch new token if cached token is close to expiry (skew check for ArithmeticOperator mutant)", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue("12345"); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("mock-key"); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue("12345"); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue("mock-key"); // Set token that expires in 60s (less than the 120s skew limit) resolver.tokenCache.set("VariaMos/VariaMosAdmin", { @@ -139,10 +150,10 @@ describe("GitHubTokenResolver - Unit Tests", () => { expiresAt: Date.now() + 60000, }); - (axios.get as jest.Mock).mockResolvedValue({ + (axios.get as vi.Mock).mockResolvedValue({ data: { id: 987 }, }); - (axios.post as jest.Mock).mockResolvedValue({ + (axios.post as vi.Mock).mockResolvedValue({ data: { token: "refreshed-token", expires_at: new Date(Date.now() + 600000).toISOString(), @@ -155,8 +166,8 @@ describe("GitHubTokenResolver - Unit Tests", () => { }); it("should fall back to personal github token if app credentials are missing", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue(undefined); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(undefined); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue(undefined); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(undefined); mockConfig.getGitHubToken.mockReturnValue(" personal-token "); const token = await resolver.resolveGitHubToken("VariaMos/VariaMosAdmin"); @@ -164,8 +175,8 @@ describe("GitHubTokenResolver - Unit Tests", () => { }); it("should return empty string and not crash if both app credentials and personal token are missing (kills optional chaining mutant)", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue(undefined); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(undefined); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue(undefined); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(undefined); const getUndefinedToken = (): string | undefined => undefined; mockConfig.getGitHubToken.mockReturnValue(getUndefinedToken() as string); @@ -175,11 +186,11 @@ describe("GitHubTokenResolver - Unit Tests", () => { }); it("should gracefully handle axios HTTP errors, log error details, and fall back to personal token", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue("12345"); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("mock-key"); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue("12345"); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue("mock-key"); mockConfig.getGitHubToken.mockReturnValue("fallback-token"); - (axios.get as jest.Mock).mockRejectedValue({ + (axios.get as vi.Mock).mockRejectedValue({ response: { data: { message: "Not Found" } }, }); @@ -193,11 +204,11 @@ describe("GitHubTokenResolver - Unit Tests", () => { }); it("should gracefully handle errors without response data, log generic error message, and fall back to personal token", async () => { - mockConfig.getGitHubAppId = jest.fn().mockReturnValue("12345"); - mockConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("mock-key"); + mockConfig.getGitHubAppId = vi.fn().mockReturnValue("12345"); + mockConfig.getGitHubPrivateKey = vi.fn().mockReturnValue("mock-key"); mockConfig.getGitHubToken.mockReturnValue("fallback-token"); - (axios.get as jest.Mock).mockRejectedValue(new Error("Network Error")); + (axios.get as vi.Mock).mockRejectedValue(new Error("Network Error")); const token = await resolver.resolveGitHubToken("VariaMos/VariaMosAdmin"); expect(token).toBe("fallback-token"); diff --git a/src/Domain/Bug/Service/GitHubTokenResolver.ts b/src/Domain/Bug/Service/GitHubTokenResolver.ts index 9d4101e..84f94c3 100644 --- a/src/Domain/Bug/Service/GitHubTokenResolver.ts +++ b/src/Domain/Bug/Service/GitHubTokenResolver.ts @@ -1,10 +1,13 @@ -import { IBugTrackerConfig } from "../Config/IBugTrackerConfig"; -import crypto from "crypto"; +import crypto from "node:crypto"; import axios from "axios"; import logger from "jet-logger"; +import type { IBugTrackerConfig } from "../Config/IBugTrackerConfig.js"; export class GitHubTokenResolver { - public readonly tokenCache = new Map(); + public readonly tokenCache = new Map< + string, + { token: string; expiresAt: number } + >(); public constructor(private readonly githubConfig: IBugTrackerConfig) {} @@ -32,7 +35,10 @@ export class GitHubTokenResolver { const installationId = installResponse.data.id; const tokenUrl = `https://api.github.com/app/installations/${installationId}/access_tokens`; - const tokenResponse = await axios.post<{ token: string; expires_at: string }>( + const tokenResponse = await axios.post<{ + token: string; + expires_at: string; + }>( tokenUrl, {}, { @@ -50,10 +56,12 @@ export class GitHubTokenResolver { this.tokenCache.set(repo, { token, expiresAt }); return token; } catch (error) { - const err = error as { response?: { data?: { message?: string } }; message?: string }; + const err = error as { + response?: { data?: { message?: string } }; + message?: string; + }; logger.err( - `Failed to resolve GitHub App token for ${repo}: ` + - (err.response?.data?.message || err.message || "Unknown error"), + `Failed to resolve GitHub App token for ${repo}: ${err.response?.data?.message || err.message || "Unknown error"}`, ); } } diff --git a/src/Domain/Bug/UseCase/BugAttachmentUseCase.test.ts b/src/Domain/Bug/UseCase/BugAttachmentUseCase.test.ts index a23c84e..fd17201 100644 --- a/src/Domain/Bug/UseCase/BugAttachmentUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugAttachmentUseCase.test.ts @@ -1,12 +1,12 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { BugAttachmentUseCase } from "./BugAttachmentUseCase"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IStorageService } from "@src/Domain/Core/Service/IStorageService"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; +import type { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment.js"; +import { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { IStorageService } from "@src/Domain/Core/Service/IStorageService.js"; import logger from "jet-logger"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { BugAttachmentUseCase } from "./BugAttachmentUseCase.js"; describe("BugAttachmentUseCase", () => { let useCase: BugAttachmentUseCase; @@ -80,15 +80,21 @@ describe("BugAttachmentUseCase", () => { bugId: "bug-123", }; mockBugRepository.findAttachmentById.mockResolvedValue( - new ResponseModel("tx-1").withResponse(mockAttachment), + new ResponseModel("tx-1").withResponse( + mockAttachment, + ), + ); + mockBugRepository.deleteAttachment.mockResolvedValue( + new ResponseModel("tx-1"), ); - mockBugRepository.deleteAttachment.mockResolvedValue(new ResponseModel("tx-1")); const req = new RequestModel("tx-1", "att-123"); const res = await useCase.deleteAttachment(req); expect(res.errorCode).toBeUndefined(); - expect(mockStorageService.deleteFile).toHaveBeenCalledWith("/uploads/file.png"); + expect(mockStorageService.deleteFile).toHaveBeenCalledWith( + "/uploads/file.png", + ); expect(mockBugRepository.deleteAttachment).toHaveBeenCalledWith(req); }); @@ -111,7 +117,7 @@ describe("BugAttachmentUseCase", () => { }); it("should proceed to delete from repository even if storage service fails to delete physical file", async () => { - const warnSpy = jest.spyOn(logger, "warn").mockImplementation(() => {}); + const warnSpy = vi.spyOn(logger, "warn").mockImplementation(() => {}); const mockAttachment: BugAttachment = { id: 1, filePath: "/uploads/file.png", @@ -119,19 +125,27 @@ describe("BugAttachmentUseCase", () => { bugId: "bug-123", }; mockBugRepository.findAttachmentById.mockResolvedValue( - new ResponseModel("tx-1").withResponse(mockAttachment), + new ResponseModel("tx-1").withResponse( + mockAttachment, + ), ); mockStorageService.deleteFile.mockRejectedValue(new Error("Disk error")); - mockBugRepository.deleteAttachment.mockResolvedValue(new ResponseModel("tx-1")); + mockBugRepository.deleteAttachment.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", "att-123"); const res = await useCase.deleteAttachment(req); expect(res.errorCode).toBeUndefined(); - expect(mockStorageService.deleteFile).toHaveBeenCalledWith("/uploads/file.png"); + expect(mockStorageService.deleteFile).toHaveBeenCalledWith( + "/uploads/file.png", + ); expect(mockBugRepository.deleteAttachment).toHaveBeenCalledWith(req); expect(warnSpy).toHaveBeenCalledWith( - expect.stringContaining("Failed to delete physical file: /uploads/file.png"), + expect.stringContaining( + "Failed to delete physical file: /uploads/file.png", + ), ); warnSpy.mockRestore(); }); @@ -144,9 +158,13 @@ describe("BugAttachmentUseCase", () => { bugId: "bug-123", }; mockBugRepository.findAttachmentById.mockResolvedValue( - new ResponseModel("tx-1").withResponse(mockAttachment), + new ResponseModel("tx-1").withResponse( + mockAttachment, + ), + ); + mockBugRepository.deleteAttachment.mockResolvedValue( + new ResponseModel("tx-1"), ); - mockBugRepository.deleteAttachment.mockResolvedValue(new ResponseModel("tx-1")); const req = new RequestModel("tx-1", "att-123"); const res = await useCase.deleteAttachment(req); @@ -164,9 +182,13 @@ describe("BugAttachmentUseCase", () => { bugId: "bug-123", }; mockBugRepository.findAttachmentById.mockResolvedValue( - new ResponseModel("tx-1").withResponse(mockAttachment), + new ResponseModel("tx-1").withResponse( + mockAttachment, + ), + ); + mockBugRepository.deleteAttachment.mockResolvedValue( + new ResponseModel("tx-1"), ); - mockBugRepository.deleteAttachment.mockResolvedValue(new ResponseModel("tx-1")); const req = new RequestModel("tx-1", "att-123"); const res = await useCase.deleteAttachment(req); @@ -189,7 +211,10 @@ describe("BugAttachmentUseCase", () => { new ResponseModel("tx-1").withResponse(mockNote), ); - const req = new RequestModel("tx-1", { bugId: "bug-123", body: "Test note body" }); + const req = new RequestModel("tx-1", { + bugId: "bug-123", + body: "Test note body", + }); const res = await useCase.createNote(req); expect(res.data).toBe(mockNote); diff --git a/src/Domain/Bug/UseCase/BugAttachmentUseCase.ts b/src/Domain/Bug/UseCase/BugAttachmentUseCase.ts index 98eb042..654ee4c 100644 --- a/src/Domain/Bug/UseCase/BugAttachmentUseCase.ts +++ b/src/Domain/Bug/UseCase/BugAttachmentUseCase.ts @@ -1,10 +1,10 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IStorageService } from "@src/Domain/Core/Service/IStorageService"; -import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; +import type { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment.js"; +import type { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IStorageService } from "@src/Domain/Core/Service/IStorageService.js"; import logger from "jet-logger"; export class BugAttachmentUseCase { @@ -25,10 +25,16 @@ export class BugAttachmentUseCase { const data = request.data; const response = new ResponseModel(request.transactionId); if (!data) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } if (!data.file) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "File is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "File is required.", + ); } const resolvedFile = { filePath: `/uploads/${data.file.filename}`, @@ -43,7 +49,9 @@ export class BugAttachmentUseCase { ); } - public async deleteAttachment(request: RequestModel): Promise> { + public async deleteAttachment( + request: RequestModel, + ): Promise> { const id = request.data; const response = new ResponseModel(request.transactionId); if (!id) { @@ -56,7 +64,10 @@ export class BugAttachmentUseCase { new RequestModel(request.transactionId, id), ); if (!attachmentResp.data) { - return response.withErrorPromise(DomainErrorCodes.ENTITY_NOT_FOUND, "Attachment not found."); + return response.withErrorPromise( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Attachment not found.", + ); } const filePath = attachmentResp.data.filePath; if (filePath && filePath !== "/purged") { diff --git a/src/Domain/Bug/UseCase/BugLifecycleUseCase.test.ts b/src/Domain/Bug/UseCase/BugLifecycleUseCase.test.ts index 427ea48..9f79267 100644 --- a/src/Domain/Bug/UseCase/BugLifecycleUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugLifecycleUseCase.test.ts @@ -1,15 +1,15 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { BugLifecycleUseCase } from "./BugLifecycleUseCase"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { IStorageService } from "@src/Domain/Core/Service/IStorageService"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService.js"; +import type { IStorageService } from "@src/Domain/Core/Service/IStorageService.js"; import logger from "jet-logger"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { BugLifecycleUseCase } from "./BugLifecycleUseCase.js"; describe("BugLifecycleUseCase", () => { let useCase: BugLifecycleUseCase; @@ -46,7 +46,9 @@ describe("BugLifecycleUseCase", () => { describe("updateStatus", () => { it("should fail update if bug not found", async () => { - mockBugRepository.findById.mockResolvedValue(new ResponseModel("tx-1")); + mockBugRepository.findById.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", { id: "nonexistent", @@ -99,7 +101,10 @@ describe("BugLifecycleUseCase", () => { new ResponseModel("tx-1").withResponse(rejectedBug), ); - const req = new RequestModel("tx-1", { id: "bug-1", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-1", + adminId: "admin-123", + }); const res = await useCase.rejectBug(req); expect(res.data?.status).toBe("rejected"); @@ -114,9 +119,14 @@ describe("BugLifecycleUseCase", () => { }); it("should fail to reject if bug is not found", async () => { - mockBugRepository.findById.mockResolvedValue(new ResponseModel("tx-1")); + mockBugRepository.findById.mockResolvedValue( + new ResponseModel("tx-1"), + ); - const req = new RequestModel("tx-1", { id: "bug-missing", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-missing", + adminId: "admin-123", + }); const res = await useCase.rejectBug(req); expect(res.errorCode).toBe(DomainErrorCodes.ENTITY_NOT_FOUND); @@ -130,7 +140,10 @@ describe("BugLifecycleUseCase", () => { new ResponseModel("tx-1").withResponse(openBug), ); - const req = new RequestModel("tx-1", { id: "bug-2", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-2", + adminId: "admin-123", + }); const res = await useCase.rejectBug(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); @@ -151,7 +164,10 @@ describe("BugLifecycleUseCase", () => { new ResponseModel("tx-1").withResponse(pendingBug), ); - const req = new RequestModel("tx-1", { id: "bug-1", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-1", + adminId: "admin-123", + }); const res = await useCase.restoreBug(req); expect(res.data?.status).toBe("pending"); @@ -166,9 +182,14 @@ describe("BugLifecycleUseCase", () => { }); it("should fail to restore if bug is not found", async () => { - mockBugRepository.findById.mockResolvedValue(new ResponseModel("tx-1")); + mockBugRepository.findById.mockResolvedValue( + new ResponseModel("tx-1"), + ); - const req = new RequestModel("tx-1", { id: "bug-missing", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-missing", + adminId: "admin-123", + }); const res = await useCase.restoreBug(req); expect(res.errorCode).toBe(DomainErrorCodes.ENTITY_NOT_FOUND); @@ -182,7 +203,10 @@ describe("BugLifecycleUseCase", () => { new ResponseModel("tx-1").withResponse(openBug), ); - const req = new RequestModel("tx-1", { id: "bug-2", adminId: "admin-123" }); + const req = new RequestModel("tx-1", { + id: "bug-2", + adminId: "admin-123", + }); const res = await useCase.restoreBug(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); @@ -195,12 +219,17 @@ describe("BugLifecycleUseCase", () => { it("should process purge for expired bugs and delete attachments", async () => { const expiredBug = createMockBug("999", "Old rejected bug", "rejected"); expiredBug.attachments = [ - { id: 1, filePath: "/uploads/old.png", fileType: "image/png", bugId: "999" }, + { + id: 1, + filePath: "/uploads/old.png", + fileType: "image/png", + bugId: "999", + }, { id: 2, filePath: "/purged", fileType: "image/png", bugId: "999" }, { id: 3, filePath: "", fileType: "image/png", bugId: "999" }, ]; - const infoLogSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const infoLogSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); mockBugRepository.findExpiredRejectedBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([expiredBug]), @@ -217,12 +246,20 @@ describe("BugLifecycleUseCase", () => { } const expectedDate = new Date(); expectedDate.setDate(expectedDate.getDate() - 7); - expect(Math.abs(dateArg.getTime() - expectedDate.getTime())).toBeLessThan(5000); + expect(Math.abs(dateArg.getTime() - expectedDate.getTime())).toBeLessThan( + 5000, + ); - expect(infoLogSpy).toHaveBeenCalledWith("Found 1 expired rejected bugs to purge."); - expect(infoLogSpy).toHaveBeenCalledWith("Expired rejected bugs purging complete."); + expect(infoLogSpy).toHaveBeenCalledWith( + "Found 1 expired rejected bugs to purge.", + ); + expect(infoLogSpy).toHaveBeenCalledWith( + "Expired rejected bugs purging complete.", + ); - expect(mockStorageService.deleteFile).toHaveBeenCalledWith("/uploads/old.png"); + expect(mockStorageService.deleteFile).toHaveBeenCalledWith( + "/uploads/old.png", + ); expect(mockStorageService.deleteFile).not.toHaveBeenCalledWith("/purged"); expect(mockStorageService.deleteFile).not.toHaveBeenCalledWith(""); @@ -267,7 +304,7 @@ describe("BugLifecycleUseCase", () => { const expiredBug = createMockBug("999", "Old rejected bug", "rejected"); expiredBug.attachments = []; - const infoLogSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const infoLogSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); mockBugRepository.findExpiredRejectedBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([expiredBug]), @@ -295,7 +332,7 @@ describe("BugLifecycleUseCase", () => { const expiredBug = createMockBug("999", "Old rejected bug", "rejected"); expiredBug.attachments = undefined; - const infoLogSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const infoLogSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); mockBugRepository.findExpiredRejectedBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([expiredBug]), @@ -319,10 +356,14 @@ describe("BugLifecycleUseCase", () => { }); it("should process purge for expired bugs with non-array attachments and not throw loop exceptions", async () => { - const expiredBugNonArray = createMockBug("999", "Old rejected bug", "rejected"); + const expiredBugNonArray = createMockBug( + "999", + "Old rejected bug", + "rejected", + ); Object.assign(expiredBugNonArray, { attachments: { notAnArray: true } }); - const infoLogSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const infoLogSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); mockBugRepository.findExpiredRejectedBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([expiredBugNonArray]), @@ -337,7 +378,7 @@ describe("BugLifecycleUseCase", () => { }); it("should return early and do nothing when no expired bugs are found", async () => { - const infoLogSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const infoLogSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); mockBugRepository.findExpiredRejectedBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([]), @@ -386,16 +427,24 @@ describe("BugLifecycleUseCase", () => { expect.objectContaining({ data: expect.objectContaining({ bugId: "bug-123", - body: expect.stringContaining("The administrator modified the following fields"), + body: expect.stringContaining( + "The administrator modified the following fields", + ), }), }), ); const noteCall = mockBugRepository.createNote.mock.calls[0][0]; - expect(noteCall.data?.body).toContain('* Description: "Old Desc" -> "New Desc"'); + expect(noteCall.data?.body).toContain( + '* Description: "Old Desc" -> "New Desc"', + ); expect(noteCall.data?.body).toContain('* Category: "Editor" -> "Model"'); expect(noteCall.data?.body).toContain('* Priority: "low" -> "high"'); - expect(noteCall.data?.body).toContain('* Target repository set to "New/Repo"'); - expect(noteCall.data?.body).toContain('\n\nAdmin Comment: "Approve change"'); + expect(noteCall.data?.body).toContain( + '* Target repository set to "New/Repo"', + ); + expect(noteCall.data?.body).toContain( + '\n\nAdmin Comment: "Approve change"', + ); }); it("should log audit comment with default fallback values when category or priority are initially missing", async () => { @@ -423,7 +472,9 @@ describe("BugLifecycleUseCase", () => { await useCase.updateStatus(req); const noteCall = mockBugRepository.createNote.mock.calls[0][0]; - expect(noteCall.data?.body).toContain('* Category: "None" -> "NewCategory"'); + expect(noteCall.data?.body).toContain( + '* Category: "None" -> "NewCategory"', + ); expect(noteCall.data?.body).toContain('* Priority: "medium" -> "high"'); }); @@ -432,7 +483,12 @@ describe("BugLifecycleUseCase", () => { bug.priority = "high"; bug.category = "Model"; bug.attachments = [ - { id: 1, filePath: "/file1.jpg", fileType: "image/jpeg", bugId: "bug-123" }, + { + id: 1, + filePath: "/file1.jpg", + fileType: "image/jpeg", + bugId: "bug-123", + }, { id: 2, filePath: "/purged", fileType: "image/png", bugId: "bug-123" }, // Should skip purged { id: 3, filePath: "/file2.png", fileType: "", bugId: "bug-123" }, // Should default to unknown type ]; @@ -445,7 +501,7 @@ describe("BugLifecycleUseCase", () => { mockBugRepository.updateStatus.mockResolvedValue( new ResponseModel("tx-1").withResponse(bug), ); - mockGithubConfig.getApiBaseUrl = jest.fn().mockReturnValue(undefined); // Fallback to http://localhost:4000 + mockGithubConfig.getApiBaseUrl = vi.fn().mockReturnValue(undefined); // Fallback to http://localhost:4000 const req = new RequestModel("tx-1", { id: "bug-123", @@ -477,7 +533,12 @@ describe("BugLifecycleUseCase", () => { it("should format attachments list with custom config API base url when pushing to GitHub", async () => { const bug = createMockBug("bug-123", "Title", "pending"); bug.attachments = [ - { id: 1, filePath: "/file1.jpg", fileType: "image/jpeg", bugId: "bug-123" }, + { + id: 1, + filePath: "/file1.jpg", + fileType: "image/jpeg", + bugId: "bug-123", + }, ]; mockBugRepository.findById.mockResolvedValue( @@ -488,7 +549,9 @@ describe("BugLifecycleUseCase", () => { mockBugRepository.updateStatus.mockResolvedValue( new ResponseModel("tx-1").withResponse(bug), ); - mockGithubConfig.getApiBaseUrl = jest.fn().mockReturnValue("https://myapi.com"); + mockGithubConfig.getApiBaseUrl = vi + .fn() + .mockReturnValue("https://myapi.com"); const req = new RequestModel("tx-1", { id: "bug-123", @@ -618,10 +681,11 @@ describe("BugLifecycleUseCase", () => { }); it("should fail update if request data is missing", async () => { - const req = new RequestModel<{ id: string; status: string; adminId: string }>( - "tx-1", - undefined, - ); + const req = new RequestModel<{ + id: string; + status: string; + adminId: string; + }>("tx-1", undefined); const res = await useCase.updateStatus(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); expect(res.message).toBe("Request data is required."); @@ -709,7 +773,9 @@ describe("BugLifecycleUseCase", () => { expect.objectContaining({ data: expect.objectContaining({ bugId: "bug-123", - body: expect.stringContaining('* Title: "Old Title" -> "New Title"'), + body: expect.stringContaining( + '* Title: "Old Title" -> "New Title"', + ), }), }), ); @@ -753,7 +819,9 @@ describe("BugLifecycleUseCase", () => { expect.objectContaining({ data: expect.objectContaining({ bugId: "bug-123", - body: expect.stringContaining("The fields were not modified by the administrator."), + body: expect.stringContaining( + "The fields were not modified by the administrator.", + ), }), }), ); @@ -919,7 +987,8 @@ describe("BugLifecycleUseCase", () => { expect.objectContaining({ data: expect.objectContaining({ gitIssueNumber: 777, - githubHtmlUrl: "https://github.com/VariaMos/VariaMosAdmin/issues/777", + githubHtmlUrl: + "https://github.com/VariaMos/VariaMosAdmin/issues/777", }), }), ); @@ -1107,7 +1176,10 @@ describe("BugLifecycleUseCase", () => { describe("rejectBug errors", () => { it("should return error if reject request data is missing", async () => { - const req = new RequestModel<{ id: string; adminId: string }>("tx-1", undefined); + const req = new RequestModel<{ id: string; adminId: string }>( + "tx-1", + undefined, + ); const res = await useCase.rejectBug(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); }); @@ -1121,7 +1193,10 @@ describe("BugLifecycleUseCase", () => { describe("restoreBug errors", () => { it("should return error if restore request data is missing", async () => { - const req = new RequestModel<{ id: string; adminId: string }>("tx-1", undefined); + const req = new RequestModel<{ id: string; adminId: string }>( + "tx-1", + undefined, + ); const res = await useCase.restoreBug(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); }); @@ -1138,12 +1213,14 @@ describe("BugLifecycleUseCase", () => { mockBugRepository.findExpiredRejectedBugs.mockImplementation(() => { throw new Error("Purge Failed"); }); - const errLogSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const errLogSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); await useCase.purgeExpiredRejectedBugs(); expect(errLogSpy).toHaveBeenCalledWith( - expect.stringContaining("Failed to purge expired rejected bugs: Purge Failed"), + expect.stringContaining( + "Failed to purge expired rejected bugs: Purge Failed", + ), ); errLogSpy.mockRestore(); }); diff --git a/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts b/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts index 45f348a..2f4b7ca 100644 --- a/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts +++ b/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts @@ -1,12 +1,12 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { IStorageService } from "@src/Domain/Core/Service/IStorageService"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService.js"; +import type { IStorageService } from "@src/Domain/Core/Service/IStorageService.js"; import logger from "jet-logger"; export class BugLifecycleUseCase { @@ -35,7 +35,10 @@ export class BugLifecycleUseCase { const data = request.data; if (!data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } if (!data.id || !data.status) { @@ -52,7 +55,10 @@ export class BugLifecycleUseCase { if (!bugResponse.data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.ENTITY_NOT_FOUND, "Bug not found."); + return response.withErrorPromise( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Bug not found.", + ); } const bug = bugResponse.data; @@ -60,12 +66,17 @@ export class BugLifecycleUseCase { try { Bug.builder() .setTitle(data.title !== undefined ? data.title : bug.title) - .setDescription(data.description !== undefined ? data.description : bug.description) + .setDescription( + data.description !== undefined ? data.description : bug.description, + ) .setPriority(data.priority !== undefined ? data.priority : bug.priority) .build(); } catch (error) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, (error as Error).message); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ); } const modifiedFields: string[] = []; @@ -73,13 +84,19 @@ export class BugLifecycleUseCase { modifiedFields.push(`* Title: "${bug.title}" -> "${data.title}"`); } if (data.description && data.description !== bug.description) { - modifiedFields.push(`* Description: "${bug.description}" -> "${data.description}"`); + modifiedFields.push( + `* Description: "${bug.description}" -> "${data.description}"`, + ); } if (data.category && data.category !== bug.category) { - modifiedFields.push(`* Category: "${bug.category || "None"}" -> "${data.category}"`); + modifiedFields.push( + `* Category: "${bug.category || "None"}" -> "${data.category}"`, + ); } if (data.priority && data.priority !== bug.priority) { - modifiedFields.push(`* Priority: "${bug.priority || "medium"}" -> "${data.priority}"`); + modifiedFields.push( + `* Priority: "${bug.priority || "medium"}" -> "${data.priority}"`, + ); } if (data.githubRepo && data.githubRepo !== bug.githubRepo) { modifiedFields.push(`* Target repository set to "${data.githubRepo}"`); @@ -95,12 +112,16 @@ export class BugLifecycleUseCase { let githubHtmlUrl: string | undefined = undefined; if (data.status === "open" && !bug.gitIssueNumber && bug.githubRepo) { - const gitHubToken = await this.tokenResolver.resolveGitHubToken(bug.githubRepo); + const gitHubToken = await this.tokenResolver.resolveGitHubToken( + bug.githubRepo, + ); if (gitHubToken) { let issueBody = bug.description || "No description provided."; issueBody += `\n\n---\n*Reported locally by: ${bug.reporterEmail || "Guest"}*`; if (data.adminEmail) { - const approvalComment = data.comment ? ` (Comment: "${data.comment}")` : ""; + const approvalComment = data.comment + ? ` (Comment: "${data.comment}")` + : ""; issueBody += `\n*Approved and pushed to GitHub by: ${data.adminEmail}${approvalComment}*`; } if (bug.priority) { @@ -111,7 +132,8 @@ export class BugLifecycleUseCase { } const attachments = bug.attachments as - { filePath?: string; fileType?: string }[] | undefined; + | { filePath?: string; fileType?: string }[] + | undefined; if (attachments && attachments.length > 0) { issueBody += "\n\n### Attachments\n"; for (const attachment of attachments) { @@ -157,7 +179,9 @@ export class BugLifecycleUseCase { } } - const approvalCommentStr = data.comment ? `\n\nAdmin Comment: "${data.comment}"` : ""; + const approvalCommentStr = data.comment + ? `\n\nAdmin Comment: "${data.comment}"` + : ""; if (data.status === "open" && modifiedFields.length > 0) { const auditBody = `[Audit] The administrator modified the following fields:\n${modifiedFields.join("\n")}${approvalCommentStr}`; @@ -192,8 +216,14 @@ export class BugLifecycleUseCase { }), ); - if (dbResponse.data && bug.githubRepo && (bug.gitIssueNumber || gitIssueNumber)) { - const gitHubToken = await this.tokenResolver.resolveGitHubToken(bug.githubRepo); + if ( + dbResponse.data && + bug.githubRepo && + (bug.gitIssueNumber || gitIssueNumber) + ) { + const gitHubToken = await this.tokenResolver.resolveGitHubToken( + bug.githubRepo, + ); const resolvedIssueNumber = bug.gitIssueNumber || gitIssueNumber; if (gitHubToken && resolvedIssueNumber) { if (data.status === "closed") { @@ -220,12 +250,18 @@ export class BugLifecycleUseCase { const data = request.data; if (!data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } if (!data.id) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Bug ID is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Bug ID is required.", + ); } const bugResponse = await this.bugRepository.findById( @@ -234,7 +270,10 @@ export class BugLifecycleUseCase { if (!bugResponse.data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.ENTITY_NOT_FOUND, "Local bug not found."); + return response.withErrorPromise( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Local bug not found.", + ); } if (bugResponse.data.status !== "pending") { @@ -260,12 +299,18 @@ export class BugLifecycleUseCase { const data = request.data; if (!data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } if (!data.id) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Bug ID is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Bug ID is required.", + ); } const bugResponse = await this.bugRepository.findById( @@ -274,7 +319,10 @@ export class BugLifecycleUseCase { if (!bugResponse.data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.ENTITY_NOT_FOUND, "Local bug not found."); + return response.withErrorPromise( + DomainErrorCodes.ENTITY_NOT_FOUND, + "Local bug not found.", + ); } if (bugResponse.data.status !== "rejected") { @@ -306,12 +354,15 @@ export class BugLifecycleUseCase { const expiredBugs = expiredResponse.data || []; if (expiredBugs.length === 0) return; - logger.info(`Found ${expiredBugs.length} expired rejected bugs to purge.`); + logger.info( + `Found ${expiredBugs.length} expired rejected bugs to purge.`, + ); for (const bug of expiredBugs) { let hasAttachments = false; const attachments = bug.attachments as - { id: number; filePath?: string; fileType?: string }[] | undefined; + | { id: number; filePath?: string; fileType?: string }[] + | undefined; if (attachments && Array.isArray(attachments)) { for (const attachment of attachments) { if (attachment.filePath && attachment.filePath !== "/purged") { diff --git a/src/Domain/Bug/UseCase/BugQueryUseCase.test.ts b/src/Domain/Bug/UseCase/BugQueryUseCase.test.ts index 1bff09f..d7baf65 100644 --- a/src/Domain/Bug/UseCase/BugQueryUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugQueryUseCase.test.ts @@ -1,14 +1,14 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { BugQueryUseCase, ALLOWED_CATEGORIES } from "./BugQueryUseCase"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter"; -import { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import type { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter.js"; +import type { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import type { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { ALLOWED_CATEGORIES, BugQueryUseCase } from "./BugQueryUseCase.js"; describe("BugQueryUseCase", () => { let useCase: BugQueryUseCase; @@ -26,7 +26,9 @@ describe("BugQueryUseCase", () => { mockBugRepository.queryBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([]), ); - mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["VariaMos/VariaMosAdmin"]); + mockGithubConfig.getGitHubManagedRepos.mockReturnValue([ + "VariaMos/VariaMosAdmin", + ]); const filter = new BugFilter("VariaMos/VariaMosAdmin"); const request = new RequestModel("tx-id", filter); await useCase.queryBugs(request); @@ -40,7 +42,9 @@ describe("BugQueryUseCase", () => { mockBugRepository.queryBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([]), ); - mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["VariaMos/VariaMosAdmin"]); + mockGithubConfig.getGitHubManagedRepos.mockReturnValue([ + "VariaMos/VariaMosAdmin", + ]); const request = new RequestModel("tx-id", new BugFilter()); await useCase.queryBugs(request); @@ -57,7 +61,9 @@ describe("BugQueryUseCase", () => { mockBugRepository.queryBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse([]), ); - mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["VariaMos/VariaMosAdmin"]); + mockGithubConfig.getGitHubManagedRepos.mockReturnValue([ + "VariaMos/VariaMosAdmin", + ]); const request = new RequestModel("tx-id", undefined); await useCase.queryBugs(request); @@ -98,7 +104,9 @@ describe("BugQueryUseCase", () => { describe("queryBugRepos", () => { it("should return the list of managed repos successfully", async () => { - mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["VariaMos/VariaMosAdmin"]); + mockGithubConfig.getGitHubManagedRepos.mockReturnValue([ + "VariaMos/VariaMosAdmin", + ]); const request = new RequestModel("tx-id"); const response = await useCase.queryBugRepos(request); diff --git a/src/Domain/Bug/UseCase/BugQueryUseCase.ts b/src/Domain/Bug/UseCase/BugQueryUseCase.ts index eb0049d..9977bd0 100644 --- a/src/Domain/Bug/UseCase/BugQueryUseCase.ts +++ b/src/Domain/Bug/UseCase/BugQueryUseCase.ts @@ -1,12 +1,12 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter"; -import { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import type { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter.js"; +import type { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import type { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import logger from "jet-logger"; export const ALLOWED_CATEGORIES = [ @@ -25,24 +25,34 @@ export class BugQueryUseCase { private readonly githubConfig: IBugTrackerConfig, ) {} - public async queryBugs(request: RequestModel): Promise> { + public async queryBugs( + request: RequestModel, + ): Promise> { const filter = request.data || new BugFilter(); if (!filter.repo) { (filter as { managedRepos?: string[] }).managedRepos = this.githubConfig.getGitHubManagedRepos(); } - return this.bugRepository.queryBugs(new RequestModel(request.transactionId, filter)); + return this.bugRepository.queryBugs( + new RequestModel(request.transactionId, filter), + ); } - public async queryLocalBugs(request: RequestModel): Promise> { + public async queryLocalBugs( + request: RequestModel, + ): Promise> { return this.bugRepository.queryLocalBugs(request); } - public async queryHistory(request: RequestModel): Promise> { + public async queryHistory( + request: RequestModel, + ): Promise> { return this.bugRepository.queryHistory(request); } - public async queryBugRepos(request: RequestModel): Promise> { + public async queryBugRepos( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { response.data = [...this.githubConfig.getGitHubManagedRepos()]; @@ -54,13 +64,17 @@ export class BugQueryUseCase { return Promise.resolve(response); } - public async queryCategories(request: RequestModel): Promise> { + public async queryCategories( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); response.data = ALLOWED_CATEGORIES; return Promise.resolve(response); } - public async queryNotes(request: RequestModel): Promise> { + public async queryNotes( + request: RequestModel, + ): Promise> { return this.bugRepository.queryNotes(request); } } diff --git a/src/Domain/Bug/UseCase/BugSubmissionUseCase.test.ts b/src/Domain/Bug/UseCase/BugSubmissionUseCase.test.ts index f781c30..2eb8e9f 100644 --- a/src/Domain/Bug/UseCase/BugSubmissionUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugSubmissionUseCase.test.ts @@ -1,14 +1,14 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { BugSubmissionUseCase } from "./BugSubmissionUseCase"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IUserRepository } from "@src/Domain/Bug/Repository/IUserRepository"; -import { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { User } from "@src/Domain/User/Entity/User"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { IUserRepository } from "@src/Domain/Bug/Repository/IUserRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { BugSubmissionUseCase } from "./BugSubmissionUseCase.js"; describe("BugSubmissionUseCase", () => { let useCase: BugSubmissionUseCase; @@ -43,7 +43,9 @@ describe("BugSubmissionUseCase", () => { .setStatus("pending") .build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const req = new RequestModel("tx-1", { title: "Guest Bug", @@ -81,7 +83,9 @@ describe("BugSubmissionUseCase", () => { ); mockTokenResolver.resolveGitHubToken.mockResolvedValue("github-token-abc"); mockIssueTracker.createIssue.mockResolvedValue(42); - mockGithubConfig.getApiBaseUrl = jest.fn().mockReturnValue("http://localhost:4000"); + mockGithubConfig.getApiBaseUrl = vi + .fn() + .mockReturnValue("http://localhost:4000"); const bug = Bug.builder() .setId("bug-456") @@ -94,7 +98,9 @@ describe("BugSubmissionUseCase", () => { .setGithubHtmlUrl("https://github.com/VariaMos/VariaMosAdmin/issues/42") .build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const req = new RequestModel("tx-1", { title: "GitHub Issue Bug", @@ -108,7 +114,9 @@ describe("BugSubmissionUseCase", () => { const res = await useCase.createBug(req); expect(res.data).toBe(bug); - expect(mockTokenResolver.resolveGitHubToken).toHaveBeenCalledWith("VariaMos/VariaMosAdmin"); + expect(mockTokenResolver.resolveGitHubToken).toHaveBeenCalledWith( + "VariaMos/VariaMosAdmin", + ); expect(mockIssueTracker.createIssue).toHaveBeenCalledWith( "VariaMos/VariaMosAdmin", "GitHub Issue Bug", @@ -164,7 +172,9 @@ describe("BugSubmissionUseCase", () => { }); const res = await useCase.createBug(req); expect(res.errorCode).toBe("INVALID_INPUT"); - expect(res.message).toBe("Bug priority must be either 'low', 'medium', or 'high'."); + expect(res.message).toBe( + "Bug priority must be either 'low', 'medium', or 'high'.", + ); }); it("should return error if category is invalid", async () => { @@ -188,7 +198,9 @@ describe("BugSubmissionUseCase", () => { }); const res = await useCase.createBug(req); expect(res.errorCode).toBe("INVALID_INPUT"); - expect(res.message).toBe("An email address is required for guest bug submissions."); + expect(res.message).toBe( + "An email address is required for guest bug submissions.", + ); }); it("should return error if reporter email cannot be resolved for admin", async () => { @@ -274,10 +286,14 @@ describe("BugSubmissionUseCase", () => { ); mockTokenResolver.resolveGitHubToken.mockResolvedValue("token"); mockIssueTracker.createIssue.mockResolvedValue(100); - mockGithubConfig.getApiBaseUrl = jest.fn().mockReturnValue("http://localhost:4000"); + mockGithubConfig.getApiBaseUrl = vi + .fn() + .mockReturnValue("http://localhost:4000"); const bug = Bug.builder().setId("bug-file").build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const req = new RequestModel("tx-1", { title: "Bug Title", @@ -317,7 +333,9 @@ describe("BugSubmissionUseCase", () => { mockGithubConfig.getApiBaseUrl = undefined; const bug = Bug.builder().setId("bug-file-default").build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const req = new RequestModel("tx-1", { title: "Bug Title", @@ -353,7 +371,9 @@ describe("BugSubmissionUseCase", () => { ); const bug = Bug.builder().setId("bug-local-admin").build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const req = new RequestModel("tx-1", { title: "Bug Title", @@ -388,10 +408,14 @@ describe("BugSubmissionUseCase", () => { ); mockTokenResolver.resolveGitHubToken.mockResolvedValue("token"); mockIssueTracker.createIssue.mockResolvedValue(101); - mockGithubConfig.getApiBaseUrl = jest.fn().mockReturnValue("http://localhost:4000"); + mockGithubConfig.getApiBaseUrl = vi + .fn() + .mockReturnValue("http://localhost:4000"); const bug = Bug.builder().setId("bug-no-priority").build(); - mockBugRepository.createBug.mockResolvedValue(new ResponseModel("tx-1").withResponse(bug)); + mockBugRepository.createBug.mockResolvedValue( + new ResponseModel("tx-1").withResponse(bug), + ); const reqData: { title: string; diff --git a/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts b/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts index 25a59b7..506dfc1 100644 --- a/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts +++ b/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts @@ -1,13 +1,13 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IUserRepository } from "@src/Domain/Bug/Repository/IUserRepository"; -import { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { ALLOWED_CATEGORIES } from "./BugQueryUseCase"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { IUserRepository } from "@src/Domain/Bug/Repository/IUserRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService.js"; +import { ALLOWED_CATEGORIES } from "./BugQueryUseCase.js"; export class BugSubmissionUseCase { public constructor( @@ -36,7 +36,10 @@ export class BugSubmissionUseCase { const data = request.data; if (!data) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Request data is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Request data is required.", + ); } if (!data.title || !data.description || !data.category) { @@ -55,7 +58,10 @@ export class BugSubmissionUseCase { .build(); } catch (error) { const response = new ResponseModel(request.transactionId); - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, (error as Error).message); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ); } if (!ALLOWED_CATEGORIES.includes(data.category)) { @@ -79,7 +85,7 @@ export class BugSubmissionUseCase { const userResponse = await this.userRepository.findSessionUser( new RequestModel(request.transactionId, data.createdById), ); - if (userResponse.data && userResponse.data.email) { + if (userResponse.data?.email) { reporterEmail = userResponse.data.email; } } @@ -92,7 +98,8 @@ export class BugSubmissionUseCase { ); } - let resolvedFile: { filePath: string; fileType: string } | undefined = undefined; + let resolvedFile: { filePath: string; fileType: string } | undefined = + undefined; if (data.file) { resolvedFile = { filePath: `/uploads/${data.file.filename}`, @@ -105,7 +112,9 @@ export class BugSubmissionUseCase { let githubHtmlUrl: string | undefined = undefined; if (data.githubRepo && data.createdById) { - const gitHubToken = await this.tokenResolver.resolveGitHubToken(data.githubRepo); + const gitHubToken = await this.tokenResolver.resolveGitHubToken( + data.githubRepo, + ); if (gitHubToken) { let issueBody = data.description || "No description provided."; issueBody += "\n\n---\n*Reported directly by Admin*"; diff --git a/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts b/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts index 235012e..e9d371c 100644 --- a/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts @@ -1,15 +1,15 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { BugSyncUseCase } from "./BugSyncUseCase"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { - IIssueTrackerService, +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { GitHubIssueLabel, -} from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; + IIssueTrackerService, +} from "@src/Domain/Core/Service/IIssueTrackerService.js"; import logger from "jet-logger"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { BugSyncUseCase } from "./BugSyncUseCase.js"; describe("BugSyncUseCase", () => { let useCase: BugSyncUseCase; @@ -32,13 +32,17 @@ describe("BugSyncUseCase", () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); it("should sync bugs successfully from GitHub issues", async () => { - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue("app-id"); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("private-key"); - mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["VariaMos/VariaMosAdmin"]); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue("app-id"); + mockGithubConfig.getGitHubPrivateKey = vi + .fn() + .mockReturnValue("private-key"); + mockGithubConfig.getGitHubManagedRepos.mockReturnValue([ + "VariaMos/VariaMosAdmin", + ]); mockTokenResolver.resolveGitHubToken.mockResolvedValue("mock-token"); mockIssueTracker.getIssues.mockResolvedValue([ @@ -53,13 +57,15 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), ); - const loggerInfoSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const loggerInfoSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); const req = new RequestModel("tx-1"); const res = await useCase.syncBugs(req); @@ -75,8 +81,8 @@ describe("BugSyncUseCase", () => { }); it("should return error if github token/app configs are not defined", async () => { - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue(undefined); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(undefined); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue(undefined); + mockGithubConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(undefined); mockGithubConfig.getGitHubToken.mockReturnValue(""); const req = new RequestModel("tx-1"); @@ -88,22 +94,24 @@ describe("BugSyncUseCase", () => { it("should fail validation if credentials contain only whitespace", async () => { // Test appId with whitespace only - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue(" "); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("private-key"); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue(" "); + mockGithubConfig.getGitHubPrivateKey = vi + .fn() + .mockReturnValue("private-key"); mockGithubConfig.getGitHubToken.mockReturnValue(""); let res = await useCase.syncBugs(new RequestModel("tx-1")); expect(res.errorCode).toBe("INVALID_INPUT"); // Test privateKey with whitespace only - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue("app-id"); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(" "); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue("app-id"); + mockGithubConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(" "); mockGithubConfig.getGitHubToken.mockReturnValue(""); res = await useCase.syncBugs(new RequestModel("tx-1")); expect(res.errorCode).toBe("INVALID_INPUT"); // Test patToken with whitespace only - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue(""); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(""); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue(""); + mockGithubConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(""); mockGithubConfig.getGitHubToken.mockReturnValue(" "); res = await useCase.syncBugs(new RequestModel("tx-1")); expect(res.errorCode).toBe("INVALID_INPUT"); @@ -111,15 +119,17 @@ describe("BugSyncUseCase", () => { it("should fail validation if only one of appId or privateKey is provided", async () => { // AppId provided, privateKey missing - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue("app-id"); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue(""); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue("app-id"); + mockGithubConfig.getGitHubPrivateKey = vi.fn().mockReturnValue(""); mockGithubConfig.getGitHubToken.mockReturnValue(""); let res = await useCase.syncBugs(new RequestModel("tx-1")); expect(res.errorCode).toBe("INVALID_INPUT"); // PrivateKey provided, appId missing - mockGithubConfig.getGitHubAppId = jest.fn().mockReturnValue(""); - mockGithubConfig.getGitHubPrivateKey = jest.fn().mockReturnValue("private-key"); + mockGithubConfig.getGitHubAppId = vi.fn().mockReturnValue(""); + mockGithubConfig.getGitHubPrivateKey = vi + .fn() + .mockReturnValue("private-key"); mockGithubConfig.getGitHubToken.mockReturnValue(""); res = await useCase.syncBugs(new RequestModel("tx-1")); expect(res.errorCode).toBe("INVALID_INPUT"); @@ -128,10 +138,12 @@ describe("BugSyncUseCase", () => { it("should skip repo if token could not be resolved", async () => { mockGithubConfig.getGitHubToken.mockReturnValue("pat-token"); mockGithubConfig.getGitHubManagedRepos.mockReturnValue(["Repo1", "Repo2"]); - mockTokenResolver.resolveGitHubToken.mockResolvedValueOnce("").mockResolvedValueOnce("token2"); + mockTokenResolver.resolveGitHubToken + .mockResolvedValueOnce("") + .mockResolvedValueOnce("token2"); mockIssueTracker.getIssues.mockResolvedValue([]); - const loggerWarnSpy = jest.spyOn(logger, "warn").mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, "warn").mockImplementation(() => {}); const req = new RequestModel("tx-1"); await useCase.syncBugs(req); @@ -168,7 +180,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -212,7 +226,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -246,15 +262,42 @@ describe("BugSyncUseCase", () => { mockTokenResolver.resolveGitHubToken.mockResolvedValue("token"); const labelsToTest = [ - { labels: [{ name: "high" }, { name: "other-label" }], expectedPriority: "high" }, - { labels: [{ name: "p1" }, { name: "other-label" }], expectedPriority: "high" }, - { labels: [{ name: "critical" }, { name: "other-label" }], expectedPriority: "high" }, - { labels: [{ name: "urg" }, { name: "other-label" }], expectedPriority: "high" }, - { labels: [{ name: "important" }, { name: "other-label" }], expectedPriority: "high" }, - { labels: [{ name: "low" }, { name: "other-label" }], expectedPriority: "low" }, - { labels: [{ name: "p3" }, { name: "other-label" }], expectedPriority: "low" }, - { labels: [{ name: "minor" }, { name: "other-label" }], expectedPriority: "low" }, - { labels: [{ name: "unknown-label" }, { name: "other-label" }], expectedPriority: "medium" }, + { + labels: [{ name: "high" }, { name: "other-label" }], + expectedPriority: "high", + }, + { + labels: [{ name: "p1" }, { name: "other-label" }], + expectedPriority: "high", + }, + { + labels: [{ name: "critical" }, { name: "other-label" }], + expectedPriority: "high", + }, + { + labels: [{ name: "urg" }, { name: "other-label" }], + expectedPriority: "high", + }, + { + labels: [{ name: "important" }, { name: "other-label" }], + expectedPriority: "high", + }, + { + labels: [{ name: "low" }, { name: "other-label" }], + expectedPriority: "low", + }, + { + labels: [{ name: "p3" }, { name: "other-label" }], + expectedPriority: "low", + }, + { + labels: [{ name: "minor" }, { name: "other-label" }], + expectedPriority: "low", + }, + { + labels: [{ name: "unknown-label" }, { name: "other-label" }], + expectedPriority: "medium", + }, ]; mockIssueTracker.getIssues.mockResolvedValue( @@ -269,7 +312,9 @@ describe("BugSyncUseCase", () => { ); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -277,7 +322,9 @@ describe("BugSyncUseCase", () => { await useCase.syncBugs(new RequestModel("tx-1")); - expect(mockBugRepository.saveOrUpdateBug).toHaveBeenCalledTimes(labelsToTest.length); + expect(mockBugRepository.saveOrUpdateBug).toHaveBeenCalledTimes( + labelsToTest.length, + ); labelsToTest.forEach((item, index) => { expect(mockBugRepository.saveOrUpdateBug).toHaveBeenNthCalledWith( index + 1, @@ -304,7 +351,11 @@ describe("BugSyncUseCase", () => { created_at: "2026-07-13T00:00:00Z", // 'critical' is high priority. 'eDiToR' (mixed case) should map to 'Editor' // We include 'other-label' to kill some -> every mutant (since length > 1) - labels: [{ name: "critical" }, { name: "eDiToR" }, { name: "other-label" }], + labels: [ + { name: "critical" }, + { name: "eDiToR" }, + { name: "other-label" }, + ], }, { number: 11, @@ -318,7 +369,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -373,7 +426,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -425,7 +480,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -477,7 +534,9 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), @@ -537,13 +596,15 @@ describe("BugSyncUseCase", () => { ]); mockBugRepository.saveOrUpdateBug.mockResolvedValue( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), ); - const loggerErrSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerErrSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); await useCase.syncBugs(new RequestModel("tx-1")); @@ -609,20 +670,26 @@ describe("BugSyncUseCase", () => { mockBugRepository.saveOrUpdateBug .mockResolvedValueOnce( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: true, updated: false, }), ) .mockResolvedValueOnce( - new ResponseModel<{ created: boolean; updated: boolean }>("tx-1").withResponse({ + new ResponseModel<{ created: boolean; updated: boolean }>( + "tx-1", + ).withResponse({ created: false, updated: true, }), ) - .mockResolvedValueOnce(new ResponseModel<{ created: boolean; updated: boolean }>("tx-1")); + .mockResolvedValueOnce( + new ResponseModel<{ created: boolean; updated: boolean }>("tx-1"), + ); - const loggerInfoSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const loggerInfoSpy = vi.spyOn(logger, "info").mockImplementation(() => {}); await useCase.syncBugs(new RequestModel("tx-1")); diff --git a/src/Domain/Bug/UseCase/BugSyncUseCase.ts b/src/Domain/Bug/UseCase/BugSyncUseCase.ts index 6d1ee8e..01b7981 100644 --- a/src/Domain/Bug/UseCase/BugSyncUseCase.ts +++ b/src/Domain/Bug/UseCase/BugSyncUseCase.ts @@ -1,13 +1,13 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository"; -import { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService"; -import { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig"; -import { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { ALLOWED_CATEGORIES } from "./BugQueryUseCase"; +import type { IBugTrackerConfig } from "@src/Domain/Bug/Config/IBugTrackerConfig.js"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import type { IBugRepository } from "@src/Domain/Bug/Repository/IBugRepository.js"; +import type { GitHubTokenResolver } from "@src/Domain/Bug/Service/GitHubTokenResolver.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IIssueTrackerService } from "@src/Domain/Core/Service/IIssueTrackerService.js"; import logger from "jet-logger"; +import { ALLOWED_CATEGORIES } from "./BugQueryUseCase.js"; export class BugSyncUseCase { public constructor( @@ -17,7 +17,9 @@ export class BugSyncUseCase { private readonly tokenResolver: GitHubTokenResolver, ) {} - public async syncBugs(request: RequestModel): Promise> { + public async syncBugs( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const appId = this.githubConfig.getGitHubAppId?.()?.trim(); @@ -31,7 +33,10 @@ export class BugSyncUseCase { logger.warn( "GitHub token is not defined in environment variables. Synchronization aborted.", ); - return response.withError(DomainErrorCodes.INVALID_INPUT, "GitHub Sync is not configured."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "GitHub Sync is not configured.", + ); } const repos = this.githubConfig.getGitHubManagedRepos(); @@ -43,7 +48,9 @@ export class BugSyncUseCase { for (const repo of repos) { const token = await this.tokenResolver.resolveGitHubToken(repo); if (!token) { - logger.warn(`GitHub token could not be resolved for repo: ${repo}. Skipping.`); + logger.warn( + `GitHub token could not be resolved for repo: ${repo}. Skipping.`, + ); continue; } const issues = await this.issueTrackerService.getIssues(repo, token); @@ -69,14 +76,17 @@ export class BugSyncUseCase { priority = "high"; } else if ( labelNames.some( - (n: string) => n.includes("low") || n.includes("p3") || n.includes("minor"), + (n: string) => + n.includes("low") || n.includes("p3") || n.includes("minor"), ) ) { priority = "low"; } for (const label of labelNames) { - const matchedCategory = ALLOWED_CATEGORIES.find((cat) => cat.toLowerCase() === label); + const matchedCategory = ALLOWED_CATEGORIES.find( + (cat) => cat.toLowerCase() === label, + ); if (matchedCategory) { category = matchedCategory; break; diff --git a/src/Domain/Core/Entity/PagedModel.ts b/src/Domain/Core/Entity/PagedModel.ts index 7dff693..f19d1da 100644 --- a/src/Domain/Core/Entity/PagedModel.ts +++ b/src/Domain/Core/Entity/PagedModel.ts @@ -1,4 +1,4 @@ -import { Nullable } from "./Nullable"; +import type { Nullable } from "./Nullable.js"; export class PagedModel { public constructor( diff --git a/src/Domain/Core/Entity/ResponseModel.spec.ts b/src/Domain/Core/Entity/ResponseModel.spec.ts index a18995f..c7bdbfa 100644 --- a/src/Domain/Core/Entity/ResponseModel.spec.ts +++ b/src/Domain/Core/Entity/ResponseModel.spec.ts @@ -1,5 +1,5 @@ -import { DomainErrorCodes } from "../Error/DomainErrorCodes"; -import { ResponseModel } from "./ResponseModel"; +import { DomainErrorCodes } from "../Error/DomainErrorCodes.js"; +import { ResponseModel } from "./ResponseModel.js"; describe("ResponseModel Entity", () => { it("should support helper promise wrappers not covered elsewhere", async () => { diff --git a/src/Domain/Core/Entity/ResponseModel.ts b/src/Domain/Core/Entity/ResponseModel.ts index 3bbb70f..9d1bdfb 100644 --- a/src/Domain/Core/Entity/ResponseModel.ts +++ b/src/Domain/Core/Entity/ResponseModel.ts @@ -1,5 +1,5 @@ -import { DomainErrorCodes } from "../Error/DomainErrorCodes"; -import { Nullable } from "./Nullable"; +import type { DomainErrorCodes } from "../Error/DomainErrorCodes.js"; +import type { Nullable } from "./Nullable.js"; export class ResponseModel { public constructor( @@ -17,7 +17,10 @@ export class ResponseModel { return this; } - public withResponsePromise(data: Nullable, totalCount?: number): Promise { + public withResponsePromise( + data: Nullable, + totalCount?: number, + ): Promise { this.data = data; this.totalCount = totalCount; @@ -31,7 +34,10 @@ export class ResponseModel { return this; } - public withErrorPromise(errorCode: DomainErrorCodes, errorMessage: string): Promise { + public withErrorPromise( + errorCode: DomainErrorCodes, + errorMessage: string, + ): Promise { this.errorCode = errorCode; this.message = errorMessage; diff --git a/src/Domain/Core/Service/IIssueTrackerService.ts b/src/Domain/Core/Service/IIssueTrackerService.ts index d66c88d..1ce7e4f 100644 --- a/src/Domain/Core/Service/IIssueTrackerService.ts +++ b/src/Domain/Core/Service/IIssueTrackerService.ts @@ -32,7 +32,15 @@ export interface IIssueTrackerService { labels: string[], token: string, ): Promise; - closeIssue(repo: string, issueNumber: number, token: string): Promise; - reopenIssue(repo: string, issueNumber: number, token: string): Promise; + closeIssue( + repo: string, + issueNumber: number, + token: string, + ): Promise; + reopenIssue( + repo: string, + issueNumber: number, + token: string, + ): Promise; getIssues(repo: string, token: string): Promise; } diff --git a/src/Domain/Countries/Entity/Country.ts b/src/Domain/Countries/Entity/Country.ts index 1e7d9a5..e227fc1 100644 --- a/src/Domain/Countries/Entity/Country.ts +++ b/src/Domain/Countries/Entity/Country.ts @@ -21,7 +21,12 @@ export class Country { if (!name || name.trim() === "") { throw new Error("Country name is required."); } - if (typeof latitude !== "number" || Number.isNaN(latitude) || latitude < -90 || latitude > 90) { + if ( + typeof latitude !== "number" || + Number.isNaN(latitude) || + latitude < -90 || + latitude > 90 + ) { throw new Error("Latitude must be a valid number between -90 and 90."); } if ( @@ -128,6 +133,12 @@ export class CountryBuilder { } public build(): Country { - return new Country(this.code, this.name, this.latitude, this.longitude, this.code3); + return new Country( + this.code, + this.name, + this.latitude, + this.longitude, + this.code3, + ); } } diff --git a/src/Domain/Countries/Repository/ICountriesRepository.ts b/src/Domain/Countries/Repository/ICountriesRepository.ts index dbf2bd3..c586aaa 100644 --- a/src/Domain/Countries/Repository/ICountriesRepository.ts +++ b/src/Domain/Countries/Repository/ICountriesRepository.ts @@ -1,9 +1,13 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Country } from "../Entity/Country"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Country } from "../Entity/Country.js"; export interface ICountriesRepository { getCountries(request: RequestModel): Promise>; - getUserCountryCode(request: RequestModel): Promise>; - getIpCountryCode(request: RequestModel): Promise>; + getUserCountryCode( + request: RequestModel, + ): Promise>; + getIpCountryCode( + request: RequestModel, + ): Promise>; } diff --git a/src/Domain/Countries/UseCase/CountriesQueryUseCase.test.ts b/src/Domain/Countries/UseCase/CountriesQueryUseCase.test.ts index b931de8..5816b4d 100644 --- a/src/Domain/Countries/UseCase/CountriesQueryUseCase.test.ts +++ b/src/Domain/Countries/UseCase/CountriesQueryUseCase.test.ts @@ -1,8 +1,8 @@ -import { CountriesQueryUseCase } from "./CountriesQueryUseCase"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; -import { Country } from "@src/Domain/Countries/Entity/Country"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Country } from "@src/Domain/Countries/Entity/Country.js"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; +import { CountriesQueryUseCase } from "./CountriesQueryUseCase.js"; describe("CountriesQueryUseCase Unit Tests", () => { describe("Country Entity & Builder", () => { @@ -102,20 +102,24 @@ describe("CountriesQueryUseCase Unit Tests", () => { .setCode3("FRA") .build(), ]; - const mockResponse = new ResponseModel("getCountries").withResponse(mockCountries); + const mockResponse = new ResponseModel( + "getCountries", + ).withResponse(mockCountries); // Create a mock of the pure Domain Interface (no data provider imports needed!) - const mockCountriesRepository: jest.Mocked = { - getCountries: jest.fn().mockResolvedValue(mockResponse), - getUserCountryCode: jest.fn(), - getIpCountryCode: jest.fn(), + const mockCountriesRepository: vi.Mocked = { + getCountries: vi.fn().mockResolvedValue(mockResponse), + getUserCountryCode: vi.fn(), + getIpCountryCode: vi.fn(), }; const request = new RequestModel("getCountries"); const useCase = new CountriesQueryUseCase(mockCountriesRepository); const result = await useCase.getCountries(request); - expect(mockCountriesRepository.getCountries).toHaveBeenCalledWith(request); + expect(mockCountriesRepository.getCountries).toHaveBeenCalledWith( + request, + ); expect(result).toEqual(mockResponse); }); }); diff --git a/src/Domain/Countries/UseCase/CountriesQueryUseCase.ts b/src/Domain/Countries/UseCase/CountriesQueryUseCase.ts index 378658a..85c164b 100644 --- a/src/Domain/Countries/UseCase/CountriesQueryUseCase.ts +++ b/src/Domain/Countries/UseCase/CountriesQueryUseCase.ts @@ -1,12 +1,16 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Country } from "@src/Domain/Countries/Entity/Country"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Country } from "@src/Domain/Countries/Entity/Country.js"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; export class CountriesQueryUseCase { - public constructor(private readonly countriesRepository: ICountriesRepository) {} + public constructor( + private readonly countriesRepository: ICountriesRepository, + ) {} - public getCountries(request: RequestModel): Promise> { + public getCountries( + request: RequestModel, + ): Promise> { return this.countriesRepository.getCountries(request); } } diff --git a/src/Domain/Menu/Entity/Menu.ts b/src/Domain/Menu/Entity/Menu.ts index 9ed38e6..f1e9d65 100644 --- a/src/Domain/Menu/Entity/Menu.ts +++ b/src/Domain/Menu/Entity/Menu.ts @@ -1,4 +1,8 @@ -export type NavigationTarget = "newWindow" | "sameWindow" | "parentContainer" | "rootContainer"; +export type NavigationTarget = + | "newWindow" + | "sameWindow" + | "parentContainer" + | "rootContainer"; export interface MenuItemBase { title: string; diff --git a/src/Domain/Metrics/Entity/Metric.test.ts b/src/Domain/Metrics/Entity/Metric.test.ts index d25fd5e..1edc97c 100644 --- a/src/Domain/Metrics/Entity/Metric.test.ts +++ b/src/Domain/Metrics/Entity/Metric.test.ts @@ -1,10 +1,18 @@ -import { Metric } from "./Metric"; +import { Metric } from "./Metric.js"; describe("Metric Entity - Unit Tests", () => { it("should successfully build a Metric using constructor", () => { const filters = ["month", "year"]; const testData = { value: 100 }; - const metric = new Metric("met-1", "Test Metric", "bar", "month", filters, "date", testData); + const metric = new Metric( + "met-1", + "Test Metric", + "bar", + "month", + filters, + "date", + testData, + ); expect(metric.getId()).toBe("met-1"); expect(metric.getTitle()).toBe("Test Metric"); diff --git a/src/Domain/Metrics/Entity/MetricsFilter.test.ts b/src/Domain/Metrics/Entity/MetricsFilter.test.ts index c82fb02..c59c1bc 100644 --- a/src/Domain/Metrics/Entity/MetricsFilter.test.ts +++ b/src/Domain/Metrics/Entity/MetricsFilter.test.ts @@ -1,4 +1,4 @@ -import { MetricsFilter } from "./MetricsFilter"; +import { MetricsFilter } from "./MetricsFilter.js"; describe("MetricsFilter Entity - Unit Tests", () => { it("should successfully build a MetricsFilter using constructor", () => { diff --git a/src/Domain/Metrics/Entity/MetricsFilter.ts b/src/Domain/Metrics/Entity/MetricsFilter.ts index e3762c8..f3136af 100644 --- a/src/Domain/Metrics/Entity/MetricsFilter.ts +++ b/src/Domain/Metrics/Entity/MetricsFilter.ts @@ -26,7 +26,11 @@ export class MetricsFilter { } public static build(builder: MetricsFilterBuilder): MetricsFilter { - return new MetricsFilter(builder.getId(), builder.getStartDate(), builder.getEndDate()); + return new MetricsFilter( + builder.getId(), + builder.getStartDate(), + builder.getEndDate(), + ); } } diff --git a/src/Domain/Metrics/Repository/IMetricsRepository.ts b/src/Domain/Metrics/Repository/IMetricsRepository.ts index 3751882..1e1845b 100644 --- a/src/Domain/Metrics/Repository/IMetricsRepository.ts +++ b/src/Domain/Metrics/Repository/IMetricsRepository.ts @@ -1,9 +1,11 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Metric } from "../Entity/Metric"; -import { MetricsFilter } from "../Entity/MetricsFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Metric } from "../Entity/Metric.js"; +import type { MetricsFilter } from "../Entity/MetricsFilter.js"; export interface IMetricsRepository { getMetrics(request: RequestModel): Promise>; - queryMetric(request: RequestModel): Promise>; + queryMetric( + request: RequestModel, + ): Promise>; } diff --git a/src/Domain/Metrics/UseCase/MetricsQueryUseCase.test.ts b/src/Domain/Metrics/UseCase/MetricsQueryUseCase.test.ts index 22e3380..6a8cee0 100644 --- a/src/Domain/Metrics/UseCase/MetricsQueryUseCase.test.ts +++ b/src/Domain/Metrics/UseCase/MetricsQueryUseCase.test.ts @@ -1,11 +1,11 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { MetricsQueryUseCase } from "./MetricsQueryUseCase"; -import { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Metric } from "@src/Domain/Metrics/Entity/Metric"; -import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Metric } from "@src/Domain/Metrics/Entity/Metric.js"; +import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter.js"; +import type { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { MetricsQueryUseCase } from "./MetricsQueryUseCase.js"; describe("MetricsQueryUseCase - Unit Tests", () => { let useCase: MetricsQueryUseCase; @@ -26,7 +26,9 @@ describe("MetricsQueryUseCase - Unit Tests", () => { .setDefaultFilter("yearly") .build(), ]; - const mockResponse = new ResponseModel("tx-1").withResponse(mockMetrics); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockMetrics, + ); mockMetricsRepository.getMetrics.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1"); @@ -53,7 +55,10 @@ describe("MetricsQueryUseCase - Unit Tests", () => { }); test("should return error if startDate is missing", async () => { - const filter = MetricsFilter.builder().setId("metric-1").setEndDate("2026-06-30").build(); + const filter = MetricsFilter.builder() + .setId("metric-1") + .setEndDate("2026-06-30") + .build(); const req = new RequestModel("tx-2", filter); const res = await useCase.queryMetric(req); @@ -63,7 +68,10 @@ describe("MetricsQueryUseCase - Unit Tests", () => { }); test("should return error if endDate is missing", async () => { - const filter = MetricsFilter.builder().setId("metric-1").setStartDate("2026-01-01").build(); + const filter = MetricsFilter.builder() + .setId("metric-1") + .setStartDate("2026-01-01") + .build(); const req = new RequestModel("tx-2", filter); const res = await useCase.queryMetric(req); @@ -116,7 +124,9 @@ describe("MetricsQueryUseCase - Unit Tests", () => { .setChartType("bar") .setDefaultFilter("yearly") .build(); - const mockResponse = new ResponseModel("tx-2").withResponse(mockMetric); + const mockResponse = new ResponseModel("tx-2").withResponse( + mockMetric, + ); mockMetricsRepository.queryMetric.mockResolvedValue(mockResponse); const res = await useCase.queryMetric(req); diff --git a/src/Domain/Metrics/UseCase/MetricsQueryUseCase.ts b/src/Domain/Metrics/UseCase/MetricsQueryUseCase.ts index 9a4cc56..832e12f 100644 --- a/src/Domain/Metrics/UseCase/MetricsQueryUseCase.ts +++ b/src/Domain/Metrics/UseCase/MetricsQueryUseCase.ts @@ -1,24 +1,32 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Metric } from "@src/Domain/Metrics/Entity/Metric"; -import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter"; -import { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { Metric } from "@src/Domain/Metrics/Entity/Metric.js"; +import type { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter.js"; +import type { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository.js"; export class MetricsQueryUseCase { public constructor(private readonly metricsRepository: IMetricsRepository) {} - public getMetrics(request: RequestModel): Promise> { + public getMetrics( + request: RequestModel, + ): Promise> { return this.metricsRepository.getMetrics(request); } - public queryMetric(request: RequestModel): Promise> { + public queryMetric( + request: RequestModel, + ): Promise> { const defaultResponse = new ResponseModel(request.transactionId); const data = request.data; if (!data?.getId()) { - return defaultResponse.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "id is required."); - } else if (!data.getStartDate() || !data.getEndDate()) { + return defaultResponse.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "id is required.", + ); + } + if (!data.getStartDate() || !data.getEndDate()) { return defaultResponse.withErrorPromise( DomainErrorCodes.INVALID_INPUT, "startDate and endDate are required.", diff --git a/src/Domain/MicroService/Entity/MicroService.test.ts b/src/Domain/MicroService/Entity/MicroService.test.ts index 232bfc6..54efe09 100644 --- a/src/Domain/MicroService/Entity/MicroService.test.ts +++ b/src/Domain/MicroService/Entity/MicroService.test.ts @@ -1,4 +1,4 @@ -import { MicroService } from "./MicroService"; +import { MicroService } from "./MicroService.js"; describe("MicroService Entity - Unit Tests", () => { const validCreated = new Date(); @@ -49,28 +49,65 @@ describe("MicroService Entity - Unit Tests", () => { it("should throw an error for empty ID", () => { expect( - () => new MicroService("", ["gateway"], validCreated, validLabels, "running", "up"), + () => + new MicroService( + "", + ["gateway"], + validCreated, + validLabels, + "running", + "up", + ), ).toThrow("Microservice ID is required."); }); it("should throw an error for empty names list", () => { - expect(() => new MicroService("s1", [], validCreated, validLabels, "running", "up")).toThrow( + expect( + () => + new MicroService("s1", [], validCreated, validLabels, "running", "up"), + ).toThrow( "Microservice names must be a non-empty list of non-empty strings.", ); - expect(() => new MicroService("s1", [""], validCreated, validLabels, "running", "up")).toThrow( + expect( + () => + new MicroService( + "s1", + [""], + validCreated, + validLabels, + "running", + "up", + ), + ).toThrow( "Microservice names must be a non-empty list of non-empty strings.", ); }); it("should throw an error for empty state", () => { - expect(() => new MicroService("s1", ["gateway"], validCreated, validLabels, "", "up")).toThrow( - "Microservice state is required.", - ); + expect( + () => + new MicroService( + "s1", + ["gateway"], + validCreated, + validLabels, + "", + "up", + ), + ).toThrow("Microservice state is required."); }); it("should throw an error for empty status", () => { expect( - () => new MicroService("s1", ["gateway"], validCreated, validLabels, "running", ""), + () => + new MicroService( + "s1", + ["gateway"], + validCreated, + validLabels, + "running", + "", + ), ).toThrow("Microservice status is required."); }); }); diff --git a/src/Domain/MicroService/Entity/MicroService.ts b/src/Domain/MicroService/Entity/MicroService.ts index feff6ba..ebf92cc 100644 --- a/src/Domain/MicroService/Entity/MicroService.ts +++ b/src/Domain/MicroService/Entity/MicroService.ts @@ -21,8 +21,14 @@ export class MicroService { if (!id || id.trim() === "") { throw new Error("Microservice ID is required."); } - if (!names || names.length === 0 || names.some((n) => !n || n.trim() === "")) { - throw new Error("Microservice names must be a non-empty list of non-empty strings."); + if ( + !names || + names.length === 0 || + names.some((n) => !n || n.trim() === "") + ) { + throw new Error( + "Microservice names must be a non-empty list of non-empty strings.", + ); } if (!state || state.trim() === "") { throw new Error("Microservice state is required."); diff --git a/src/Domain/MicroService/Entity/MicroServiceFilter.ts b/src/Domain/MicroService/Entity/MicroServiceFilter.ts index c2a9163..76a03c3 100644 --- a/src/Domain/MicroService/Entity/MicroServiceFilter.ts +++ b/src/Domain/MicroService/Entity/MicroServiceFilter.ts @@ -1,5 +1,5 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class MicroServiceFilter extends PagedModel { public constructor( @@ -15,7 +15,11 @@ export class MicroServiceFilter extends PagedModel { } public static build(builder: MicroServiceFilterBuilder): MicroServiceFilter { - return new MicroServiceFilter(builder.name ?? undefined, builder.pageNumber, builder.pageSize); + return new MicroServiceFilter( + builder.name ?? undefined, + builder.pageNumber, + builder.pageSize, + ); } } diff --git a/src/Domain/MicroService/Repository/IMicroServiceRepository.ts b/src/Domain/MicroService/Repository/IMicroServiceRepository.ts index b890140..2757e3e 100644 --- a/src/Domain/MicroService/Repository/IMicroServiceRepository.ts +++ b/src/Domain/MicroService/Repository/IMicroServiceRepository.ts @@ -1,16 +1,22 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroService } from "../Entity/MicroService"; -import { MicroServiceFilter } from "../Entity/MicroServiceFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { MicroService } from "../Entity/MicroService.js"; +import type { MicroServiceFilter } from "../Entity/MicroServiceFilter.js"; export interface IMicroServiceRepository { queryMicroServices( request: RequestModel, ): Promise>; - queryById(request: RequestModel): Promise>; - startMicroService(request: RequestModel): Promise>; + queryById( + request: RequestModel, + ): Promise>; + startMicroService( + request: RequestModel, + ): Promise>; stopMicroService(request: RequestModel): Promise>; - restartMicroService(request: RequestModel): Promise>; + restartMicroService( + request: RequestModel, + ): Promise>; watchMicroServiceLogs( request: RequestModel, ): Promise>; diff --git a/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.test.ts b/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.test.ts index 05bc511..4b7f76e 100644 --- a/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.test.ts +++ b/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.test.ts @@ -1,10 +1,10 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { MicroServiceManagementUseCase } from "./MicroServiceManagementUseCase"; -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroService } from "@src/Domain/MicroService/Entity/MicroService"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { MicroService } from "@src/Domain/MicroService/Entity/MicroService.js"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { MicroServiceManagementUseCase } from "./MicroServiceManagementUseCase.js"; describe("MicroServiceManagementUseCase - Unit Tests", () => { let useCase: MicroServiceManagementUseCase; @@ -22,7 +22,7 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { .setCreated(new Date()) .setLabels({ key: "val" }) .setState(state) - .setStatus("Status: " + state) + .setStatus(`Status: ${state}`) .build(); }; @@ -33,14 +33,15 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); expect(res.message).toBe("MicroService Id is required."); - expect(mockMicroServiceRepository.startMicroService).not.toHaveBeenCalled(); + expect( + mockMicroServiceRepository.startMicroService, + ).not.toHaveBeenCalled(); }); test("should return error if queryById returns error", async () => { - const mockQueryResponse = new ResponseModel("tx-1").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "Service not found", - ); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Service not found"); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -48,12 +49,16 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { expect(res.errorCode).toBe(DomainErrorCodes.ENTITY_NOT_FOUND); expect(res.message).toBe("Service not found"); - expect(mockMicroServiceRepository.startMicroService).not.toHaveBeenCalled(); + expect( + mockMicroServiceRepository.startMicroService, + ).not.toHaveBeenCalled(); }); test("should return error if microservice state is not exited", async () => { const mockService = createMockService("ms-1", "running"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -61,22 +66,30 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); expect(res.message).toBe("MicroService is not in exited state."); - expect(mockMicroServiceRepository.startMicroService).not.toHaveBeenCalled(); + expect( + mockMicroServiceRepository.startMicroService, + ).not.toHaveBeenCalled(); }); test("should start microservice if state is exited", async () => { const mockService = createMockService("ms-1", "exited"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const mockSuccessResponse = new ResponseModel("tx-1"); - mockMicroServiceRepository.startMicroService.mockResolvedValue(mockSuccessResponse); + mockMicroServiceRepository.startMicroService.mockResolvedValue( + mockSuccessResponse, + ); const req = new RequestModel("tx-1", "ms-1"); const res = await useCase.startMicroService(req); expect(res.errorCode).toBeUndefined(); - expect(mockMicroServiceRepository.startMicroService).toHaveBeenCalledWith(req); + expect(mockMicroServiceRepository.startMicroService).toHaveBeenCalledWith( + req, + ); }); }); @@ -90,10 +103,9 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { }); test("should return error if queryById returns error", async () => { - const mockQueryResponse = new ResponseModel("tx-1").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "Service not found", - ); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Service not found"); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -104,7 +116,9 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { test("should return error if microservice state is not running", async () => { const mockService = createMockService("ms-1", "exited"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -116,17 +130,23 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { test("should stop microservice if state is running", async () => { const mockService = createMockService("ms-1", "running"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const mockSuccessResponse = new ResponseModel("tx-1"); - mockMicroServiceRepository.stopMicroService.mockResolvedValue(mockSuccessResponse); + mockMicroServiceRepository.stopMicroService.mockResolvedValue( + mockSuccessResponse, + ); const req = new RequestModel("tx-1", "ms-1"); const res = await useCase.stopMicroService(req); expect(res.errorCode).toBeUndefined(); - expect(mockMicroServiceRepository.stopMicroService).toHaveBeenCalledWith(req); + expect(mockMicroServiceRepository.stopMicroService).toHaveBeenCalledWith( + req, + ); }); }); @@ -140,10 +160,9 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { }); test("should return error if queryById returns error", async () => { - const mockQueryResponse = new ResponseModel("tx-1").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "Service not found", - ); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Service not found"); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -154,7 +173,9 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { test("should return error if microservice state is not running", async () => { const mockService = createMockService("ms-1", "exited"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const req = new RequestModel("tx-1", "ms-1"); @@ -166,17 +187,23 @@ describe("MicroServiceManagementUseCase - Unit Tests", () => { test("should restart microservice if state is running", async () => { const mockService = createMockService("ms-1", "running"); - const mockQueryResponse = new ResponseModel("tx-1").withResponse(mockService); + const mockQueryResponse = new ResponseModel( + "tx-1", + ).withResponse(mockService); mockMicroServiceRepository.queryById.mockResolvedValue(mockQueryResponse); const mockSuccessResponse = new ResponseModel("tx-1"); - mockMicroServiceRepository.restartMicroService.mockResolvedValue(mockSuccessResponse); + mockMicroServiceRepository.restartMicroService.mockResolvedValue( + mockSuccessResponse, + ); const req = new RequestModel("tx-1", "ms-1"); const res = await useCase.restartMicroService(req); expect(res.errorCode).toBeUndefined(); - expect(mockMicroServiceRepository.restartMicroService).toHaveBeenCalledWith(req); + expect( + mockMicroServiceRepository.restartMicroService, + ).toHaveBeenCalledWith(req); }); test("should fallback to default error message if queryById returns error without message", async () => { diff --git a/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.ts b/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.ts index 6ef4aad..78b5ec7 100644 --- a/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.ts +++ b/src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.ts @@ -1,12 +1,16 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; export class MicroServiceManagementUseCase { - public constructor(private readonly microServiceRepository: IMicroServiceRepository) {} + public constructor( + private readonly microServiceRepository: IMicroServiceRepository, + ) {} - public async startMicroService(request: RequestModel): Promise> { + public async startMicroService( + request: RequestModel, + ): Promise> { const defaultResponse = new ResponseModel(request.transactionId); if (!request.data) { return defaultResponse.withError( @@ -15,7 +19,8 @@ export class MicroServiceManagementUseCase { ); } - const microserviceResponse = await this.microServiceRepository.queryById(request); + const microserviceResponse = + await this.microServiceRepository.queryById(request); if (microserviceResponse.errorCode) { return defaultResponse.withError( @@ -34,7 +39,9 @@ export class MicroServiceManagementUseCase { return this.microServiceRepository.startMicroService(request); } - public async stopMicroService(request: RequestModel): Promise> { + public async stopMicroService( + request: RequestModel, + ): Promise> { const defaultResponse = new ResponseModel(request.transactionId); if (!request.data) { return defaultResponse.withError( @@ -43,7 +50,8 @@ export class MicroServiceManagementUseCase { ); } - const microserviceResponse = await this.microServiceRepository.queryById(request); + const microserviceResponse = + await this.microServiceRepository.queryById(request); if (microserviceResponse.errorCode) { return defaultResponse.withError( @@ -62,7 +70,9 @@ export class MicroServiceManagementUseCase { return this.microServiceRepository.stopMicroService(request); } - public async restartMicroService(request: RequestModel): Promise> { + public async restartMicroService( + request: RequestModel, + ): Promise> { const defaultResponse = new ResponseModel(request.transactionId); if (!request.data) { return defaultResponse.withError( @@ -71,7 +81,8 @@ export class MicroServiceManagementUseCase { ); } - const microserviceResponse = await this.microServiceRepository.queryById(request); + const microserviceResponse = + await this.microServiceRepository.queryById(request); if (microserviceResponse.errorCode) { return defaultResponse.withError( diff --git a/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.test.ts b/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.test.ts index 5d02dad..1e67fa4 100644 --- a/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.test.ts +++ b/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.test.ts @@ -1,12 +1,12 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { MicroServiceQueryUseCase } from "./MicroServiceQueryUseCase"; -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroService } from "@src/Domain/MicroService/Entity/MicroService"; -import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { Readable } from "stream"; +import { Readable } from "node:stream"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { MicroService } from "@src/Domain/MicroService/Entity/MicroService.js"; +import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { MicroServiceQueryUseCase } from "./MicroServiceQueryUseCase.js"; describe("MicroServiceQueryUseCase - Unit Tests", () => { let useCase: MicroServiceQueryUseCase; @@ -24,21 +24,27 @@ describe("MicroServiceQueryUseCase - Unit Tests", () => { .setCreated(new Date()) .setLabels({ key: "val" }) .setState(state) - .setStatus("Status: " + state) + .setStatus(`Status: ${state}`) .build(); }; test("should query microservices", async () => { const filter = new MicroServiceFilter(); const mockServices = [createMockService("ms-1", "running")]; - const mockResponse = new ResponseModel("tx-1").withResponse(mockServices); - mockMicroServiceRepository.queryMicroServices.mockResolvedValue(mockResponse); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockServices, + ); + mockMicroServiceRepository.queryMicroServices.mockResolvedValue( + mockResponse, + ); const req = new RequestModel("tx-1", filter); const res = await useCase.queryMicroServices(req); expect(res.data).toBe(mockServices); - expect(mockMicroServiceRepository.queryMicroServices).toHaveBeenCalledWith(req); + expect(mockMicroServiceRepository.queryMicroServices).toHaveBeenCalledWith( + req, + ); }); describe("watchMicroServiceLogs", () => { @@ -52,16 +58,20 @@ describe("MicroServiceQueryUseCase - Unit Tests", () => { test("should watch microservice logs successfully", async () => { const mockStream = new Readable(); - const mockResponse = new ResponseModel("tx-1").withResponse( - mockStream, + const mockResponse = new ResponseModel( + "tx-1", + ).withResponse(mockStream); + mockMicroServiceRepository.watchMicroServiceLogs.mockResolvedValue( + mockResponse, ); - mockMicroServiceRepository.watchMicroServiceLogs.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", "ms-1"); const res = await useCase.watchMicroServiceLogs(req); expect(res.data).toBe(mockStream); - expect(mockMicroServiceRepository.watchMicroServiceLogs).toHaveBeenCalledWith(req); + expect( + mockMicroServiceRepository.watchMicroServiceLogs, + ).toHaveBeenCalledWith(req); }); }); }); diff --git a/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.ts b/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.ts index afb9136..d16d824 100644 --- a/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.ts +++ b/src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.ts @@ -1,12 +1,14 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroService } from "@src/Domain/MicroService/Entity/MicroService"; -import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter"; -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { MicroService } from "@src/Domain/MicroService/Entity/MicroService.js"; +import type { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; export class MicroServiceQueryUseCase { - public constructor(private readonly microServiceRepository: IMicroServiceRepository) {} + public constructor( + private readonly microServiceRepository: IMicroServiceRepository, + ) {} public queryMicroServices( request: RequestModel, @@ -17,7 +19,9 @@ export class MicroServiceQueryUseCase { public async watchMicroServiceLogs( request: RequestModel, ): Promise> { - const defaultResponse = new ResponseModel(request.transactionId); + const defaultResponse = new ResponseModel( + request.transactionId, + ); if (!request.data) { return defaultResponse.withError( diff --git a/src/Domain/Permission/Entity/Permission.test.ts b/src/Domain/Permission/Entity/Permission.test.ts index e54ed1e..110fb70 100644 --- a/src/Domain/Permission/Entity/Permission.test.ts +++ b/src/Domain/Permission/Entity/Permission.test.ts @@ -1,4 +1,4 @@ -import { Permission } from "./Permission"; +import { Permission } from "./Permission.js"; describe("Permission Entity - Unit Tests", () => { it("should build a Permission successfully", () => { @@ -6,7 +6,10 @@ describe("Permission Entity - Unit Tests", () => { expect(permission1.id).toBe(1); expect(permission1.name).toBe("my-account::query"); - const permission2 = Permission.builder().setId(2).setName("languages::create").build(); + const permission2 = Permission.builder() + .setId(2) + .setName("languages::create") + .build(); expect(permission2.id).toBe(2); expect(permission2.name).toBe("languages::create"); diff --git a/src/Domain/Permission/Entity/Permission.ts b/src/Domain/Permission/Entity/Permission.ts index 29d0e50..4f42c4f 100644 --- a/src/Domain/Permission/Entity/Permission.ts +++ b/src/Domain/Permission/Entity/Permission.ts @@ -1,10 +1,11 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; export class Permission { public readonly id: Nullable; public readonly name: string; - private static readonly PERMISSION_NAME_REGEX = /^(?:[a-z0-9-]+::)?[a-z0-9-]+::[a-z0-9-]+$/; + private static readonly PERMISSION_NAME_REGEX = + /^(?:[a-z0-9-]+::)?[a-z0-9-]+::[a-z0-9-]+$/; public constructor(id: Nullable, name: string) { if (!name || !Permission.PERMISSION_NAME_REGEX.test(name)) { diff --git a/src/Domain/Permission/Entity/PermissionFilter.ts b/src/Domain/Permission/Entity/PermissionFilter.ts index 3c7c74e..2566a22 100644 --- a/src/Domain/Permission/Entity/PermissionFilter.ts +++ b/src/Domain/Permission/Entity/PermissionFilter.ts @@ -1,5 +1,5 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class PermissionFilter extends PagedModel { public constructor( @@ -16,7 +16,12 @@ export class PermissionFilter extends PagedModel { } public static build(builder: PermissionFilterBuilder): PermissionFilter { - return new PermissionFilter(builder.id, builder.name, builder.pageNumber, builder.pageSize); + return new PermissionFilter( + builder.id, + builder.name, + builder.pageNumber, + builder.pageSize, + ); } } diff --git a/src/Domain/Permission/Repository/IPermissionRepository.ts b/src/Domain/Permission/Repository/IPermissionRepository.ts index ec15bde..7b81403 100644 --- a/src/Domain/Permission/Repository/IPermissionRepository.ts +++ b/src/Domain/Permission/Repository/IPermissionRepository.ts @@ -1,12 +1,18 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "../Entity/Permission"; -import { PermissionFilter } from "../Entity/PermissionFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Permission } from "../Entity/Permission.js"; +import type { PermissionFilter } from "../Entity/PermissionFilter.js"; export interface IPermissionRepository { - queryPermissions(request: RequestModel): Promise>; - createPermission(request: RequestModel): Promise>; + queryPermissions( + request: RequestModel, + ): Promise>; + createPermission( + request: RequestModel, + ): Promise>; deletePermission(request: RequestModel): Promise>; queryById(request: RequestModel): Promise>; - updatePermission(request: RequestModel): Promise>; + updatePermission( + request: RequestModel, + ): Promise>; } diff --git a/src/Domain/Permission/UseCase/PermissionUseCase.test.ts b/src/Domain/Permission/UseCase/PermissionUseCase.test.ts index 6b5daa1..d341eee 100644 --- a/src/Domain/Permission/UseCase/PermissionUseCase.test.ts +++ b/src/Domain/Permission/UseCase/PermissionUseCase.test.ts @@ -1,10 +1,10 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { PermissionUseCase } from "./PermissionUseCase"; -import { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; +import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { PermissionUseCase } from "./PermissionUseCase.js"; describe("PermissionUseCase - Unit Tests", () => { let useCase: PermissionUseCase; @@ -18,7 +18,9 @@ describe("PermissionUseCase - Unit Tests", () => { test("should query permissions", async () => { const mockFilter = new PermissionFilter(1, "permissions::query"); const mockPermissions = [new Permission(1, "permissions::query")]; - const mockResponse = new ResponseModel("tx-1").withResponse(mockPermissions); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockPermissions, + ); mockPermissionRepository.queryPermissions.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", mockFilter); @@ -31,7 +33,9 @@ describe("PermissionUseCase - Unit Tests", () => { test("should create permission", async () => { const mockPermission = new Permission(null, "permissions::create"); const createdPermission = new Permission(2, "permissions::create"); - const mockResponse = new ResponseModel("tx-2").withResponse(createdPermission); + const mockResponse = new ResponseModel("tx-2").withResponse( + createdPermission, + ); mockPermissionRepository.createPermission.mockResolvedValue(mockResponse); const req = new RequestModel("tx-2", mockPermission); @@ -54,7 +58,9 @@ describe("PermissionUseCase - Unit Tests", () => { test("should query permission by id", async () => { const mockPermission = new Permission(1, "permissions::query"); - const mockResponse = new ResponseModel("tx-4").withResponse(mockPermission); + const mockResponse = new ResponseModel("tx-4").withResponse( + mockPermission, + ); mockPermissionRepository.queryById.mockResolvedValue(mockResponse); const req = new RequestModel("tx-4", 1); @@ -66,7 +72,9 @@ describe("PermissionUseCase - Unit Tests", () => { test("should update permission", async () => { const mockPermission = new Permission(1, "permissions::update"); - const mockResponse = new ResponseModel("tx-5").withResponse(mockPermission); + const mockResponse = new ResponseModel("tx-5").withResponse( + mockPermission, + ); mockPermissionRepository.updatePermission.mockResolvedValue(mockResponse); const req = new RequestModel("tx-5", mockPermission); diff --git a/src/Domain/Permission/UseCase/PermissionUseCase.ts b/src/Domain/Permission/UseCase/PermissionUseCase.ts index 11ccd6f..be2af99 100644 --- a/src/Domain/Permission/UseCase/PermissionUseCase.ts +++ b/src/Domain/Permission/UseCase/PermissionUseCase.ts @@ -1,11 +1,13 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter"; -import { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import type { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; +import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; export class PermissionUseCase { - public constructor(private readonly permissionRepository: IPermissionRepository) {} + public constructor( + private readonly permissionRepository: IPermissionRepository, + ) {} public queryPermissions( request: RequestModel, @@ -13,19 +15,27 @@ export class PermissionUseCase { return this.permissionRepository.queryPermissions(request); } - public createPermission(request: RequestModel): Promise> { + public createPermission( + request: RequestModel, + ): Promise> { return this.permissionRepository.createPermission(request); } - public deletePermission(request: RequestModel): Promise> { + public deletePermission( + request: RequestModel, + ): Promise> { return this.permissionRepository.deletePermission(request); } - public queryById(request: RequestModel): Promise> { + public queryById( + request: RequestModel, + ): Promise> { return this.permissionRepository.queryById(request); } - public updatePermission(request: RequestModel): Promise> { + public updatePermission( + request: RequestModel, + ): Promise> { return this.permissionRepository.updatePermission(request); } } diff --git a/src/Domain/Role/Entity/Role.test.ts b/src/Domain/Role/Entity/Role.test.ts index b78b96c..ebd753c 100644 --- a/src/Domain/Role/Entity/Role.test.ts +++ b/src/Domain/Role/Entity/Role.test.ts @@ -1,4 +1,4 @@ -import { Role } from "./Role"; +import { Role } from "./Role.js"; describe("Role Entity - Unit Tests", () => { it("should build a Role successfully with valid names", () => { diff --git a/src/Domain/Role/Entity/Role.ts b/src/Domain/Role/Entity/Role.ts index b3ace6c..86d77de 100644 --- a/src/Domain/Role/Entity/Role.ts +++ b/src/Domain/Role/Entity/Role.ts @@ -1,14 +1,19 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import type { Permission } from "@src/Domain/Permission/Entity/Permission.js"; export class Role { public readonly id: Nullable; public readonly name: string; public readonly permissions?: Permission[]; - private static readonly ROLE_NAME_REGEX = /^[A-Z][a-z]*(?:\s[A-Za-z][a-z]*)*$/; + private static readonly ROLE_NAME_REGEX = + /^[A-Z][a-z]*(?:\s[A-Za-z][a-z]*)*$/; - public constructor(id: Nullable, name: string, permissions?: Permission[]) { + public constructor( + id: Nullable, + name: string, + permissions?: Permission[], + ) { if (!name || !Role.ROLE_NAME_REGEX.test(name)) { throw new Error( "Role name must start with an uppercase letter, and subsequent words must start with a letter.", diff --git a/src/Domain/Role/Entity/RoleFilter.ts b/src/Domain/Role/Entity/RoleFilter.ts index 129529d..1423d7f 100644 --- a/src/Domain/Role/Entity/RoleFilter.ts +++ b/src/Domain/Role/Entity/RoleFilter.ts @@ -1,5 +1,5 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class RoleFilter extends PagedModel { public constructor( @@ -16,7 +16,12 @@ export class RoleFilter extends PagedModel { } public static build(builder: RoleFilterBuilder): RoleFilter { - return new RoleFilter(builder.id, builder.name, builder.pageNumber, builder.pageSize); + return new RoleFilter( + builder.id, + builder.name, + builder.pageNumber, + builder.pageSize, + ); } } diff --git a/src/Domain/Role/Entity/RolePermission.ts b/src/Domain/Role/Entity/RolePermission.ts index 0d670c5..b5f28d9 100644 --- a/src/Domain/Role/Entity/RolePermission.ts +++ b/src/Domain/Role/Entity/RolePermission.ts @@ -1,4 +1,4 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; export class RolePermission { public roleId: Nullable; diff --git a/src/Domain/Role/Entity/RolePermissionFilter.ts b/src/Domain/Role/Entity/RolePermissionFilter.ts index 3fed54f..a66c62b 100644 --- a/src/Domain/Role/Entity/RolePermissionFilter.ts +++ b/src/Domain/Role/Entity/RolePermissionFilter.ts @@ -1,4 +1,4 @@ -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class RolePermissionFilter extends PagedModel { public constructor( @@ -13,8 +13,14 @@ export class RolePermissionFilter extends PagedModel { return new RolePermissionFilterBuilder(); } - public static build(builder: RolePermissionFilterBuilder): RolePermissionFilter { - return new RolePermissionFilter(builder.roleId, builder.pageNumber, builder.pageSize); + public static build( + builder: RolePermissionFilterBuilder, + ): RolePermissionFilter { + return new RolePermissionFilter( + builder.roleId, + builder.pageNumber, + builder.pageSize, + ); } } diff --git a/src/Domain/Role/IRoleRepository.ts b/src/Domain/Role/IRoleRepository.ts index aca599d..ac3ed62 100644 --- a/src/Domain/Role/IRoleRepository.ts +++ b/src/Domain/Role/IRoleRepository.ts @@ -1,6 +1,6 @@ -import { RequestModel } from "../Core/Entity/RequestModel"; -import { ResponseModel } from "../Core/Entity/ResponseModel"; -import { Role } from "./Entity/Role"; +import type { RequestModel } from "../Core/Entity/RequestModel.js"; +import type { ResponseModel } from "../Core/Entity/ResponseModel.js"; +import type { Role } from "./Entity/Role.js"; export interface IRoleRepository { queryGuestRole(request: RequestModel): Promise>; diff --git a/src/Domain/Role/Repository/IGuestRoleRepository.ts b/src/Domain/Role/Repository/IGuestRoleRepository.ts index ad18a23..ffacec0 100644 --- a/src/Domain/Role/Repository/IGuestRoleRepository.ts +++ b/src/Domain/Role/Repository/IGuestRoleRepository.ts @@ -1,6 +1,6 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "../Entity/Role"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "../Entity/Role.js"; export interface IGuestRoleRepository { queryGuestRole(request: RequestModel): Promise>; diff --git a/src/Domain/Role/Repository/IRolePermissionRepository.ts b/src/Domain/Role/Repository/IRolePermissionRepository.ts index fa71877..18b36ec 100644 --- a/src/Domain/Role/Repository/IRolePermissionRepository.ts +++ b/src/Domain/Role/Repository/IRolePermissionRepository.ts @@ -1,8 +1,8 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { RolePermission } from "../Entity/RolePermission"; -import { RolePermissionFilter } from "../Entity/RolePermissionFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import type { RolePermission } from "../Entity/RolePermission.js"; +import type { RolePermissionFilter } from "../Entity/RolePermissionFilter.js"; export interface IRolePermissionRepository { queryRolePermissions( @@ -11,5 +11,7 @@ export interface IRolePermissionRepository { createRolePermission( request: RequestModel, ): Promise>; - deleteRolePermission(request: RequestModel): Promise>; + deleteRolePermission( + request: RequestModel, + ): Promise>; } diff --git a/src/Domain/Role/Repository/IRoleRepository.ts b/src/Domain/Role/Repository/IRoleRepository.ts index d2cacc3..7877654 100644 --- a/src/Domain/Role/Repository/IRoleRepository.ts +++ b/src/Domain/Role/Repository/IRoleRepository.ts @@ -1,7 +1,7 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "../Entity/Role"; -import { RoleFilter } from "../Entity/RoleFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "../Entity/Role.js"; +import type { RoleFilter } from "../Entity/RoleFilter.js"; export interface IRoleRepository { queryRoles(request: RequestModel): Promise>; diff --git a/src/Domain/Role/UseCase/RoleManagementUseCase.test.ts b/src/Domain/Role/UseCase/RoleManagementUseCase.test.ts index 393d789..6a4fd99 100644 --- a/src/Domain/Role/UseCase/RoleManagementUseCase.test.ts +++ b/src/Domain/Role/UseCase/RoleManagementUseCase.test.ts @@ -1,9 +1,9 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { RoleManagementUseCase } from "./RoleManagementUseCase"; -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { RoleManagementUseCase } from "./RoleManagementUseCase.js"; describe("RoleManagementUseCase - Unit Tests", () => { let useCase: RoleManagementUseCase; @@ -17,7 +17,9 @@ describe("RoleManagementUseCase - Unit Tests", () => { test("should create role", async () => { const mockRole = new Role(null, "User"); const createdRole = new Role(2, "User"); - const mockResponse = new ResponseModel("tx-2").withResponse(createdRole); + const mockResponse = new ResponseModel("tx-2").withResponse( + createdRole, + ); mockRoleRepository.createRole.mockResolvedValue(mockResponse); const req = new RequestModel("tx-2", mockRole); diff --git a/src/Domain/Role/UseCase/RoleManagementUseCase.ts b/src/Domain/Role/UseCase/RoleManagementUseCase.ts index a3ca69e..0369288 100644 --- a/src/Domain/Role/UseCase/RoleManagementUseCase.ts +++ b/src/Domain/Role/UseCase/RoleManagementUseCase.ts @@ -1,7 +1,7 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; export class RoleManagementUseCase { public constructor(private readonly roleRepository: IRoleRepository) {} @@ -10,7 +10,9 @@ export class RoleManagementUseCase { return this.roleRepository.createRole(request); } - public deleteRole(request: RequestModel): Promise> { + public deleteRole( + request: RequestModel, + ): Promise> { return this.roleRepository.deleteRole(request); } diff --git a/src/Domain/Role/UseCase/RolePermissionUseCase.test.ts b/src/Domain/Role/UseCase/RolePermissionUseCase.test.ts index 9af7e72..bbfc6dd 100644 --- a/src/Domain/Role/UseCase/RolePermissionUseCase.test.ts +++ b/src/Domain/Role/UseCase/RolePermissionUseCase.test.ts @@ -1,11 +1,11 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { RolePermissionUseCase } from "./RolePermissionUseCase"; -import { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { RolePermission } from "@src/Domain/Role/Entity/RolePermission"; -import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; +import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter.js"; +import type { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { RolePermissionUseCase } from "./RolePermissionUseCase.js"; describe("RolePermissionUseCase - Unit Tests", () => { let useCase: RolePermissionUseCase; @@ -19,37 +19,53 @@ describe("RolePermissionUseCase - Unit Tests", () => { test("should query role permissions", async () => { const mockFilter = new RolePermissionFilter(1); const mockPermissions = [new Permission(1, "roles::read")]; - const mockResponse = new ResponseModel("tx-1").withResponse(mockPermissions); - mockRolePermissionRepository.queryRolePermissions.mockResolvedValue(mockResponse); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockPermissions, + ); + mockRolePermissionRepository.queryRolePermissions.mockResolvedValue( + mockResponse, + ); const req = new RequestModel("tx-1", mockFilter); const res = await useCase.queryRolePermissions(req); expect(res.data).toBe(mockPermissions); - expect(mockRolePermissionRepository.queryRolePermissions).toHaveBeenCalledWith(req); + expect( + mockRolePermissionRepository.queryRolePermissions, + ).toHaveBeenCalledWith(req); }); test("should create role permission", async () => { const mockRolePermission = new RolePermission(1, 2); - const mockResponse = new ResponseModel("tx-2").withResponse(mockRolePermission); - mockRolePermissionRepository.createRolePermission.mockResolvedValue(mockResponse); + const mockResponse = new ResponseModel("tx-2").withResponse( + mockRolePermission, + ); + mockRolePermissionRepository.createRolePermission.mockResolvedValue( + mockResponse, + ); const req = new RequestModel("tx-2", mockRolePermission); const res = await useCase.createRolePermission(req); expect(res.data).toBe(mockRolePermission); - expect(mockRolePermissionRepository.createRolePermission).toHaveBeenCalledWith(req); + expect( + mockRolePermissionRepository.createRolePermission, + ).toHaveBeenCalledWith(req); }); test("should delete role permission", async () => { const mockRolePermission = new RolePermission(1, 2); const mockResponse = new ResponseModel("tx-3"); - mockRolePermissionRepository.deleteRolePermission.mockResolvedValue(mockResponse); + mockRolePermissionRepository.deleteRolePermission.mockResolvedValue( + mockResponse, + ); const req = new RequestModel("tx-3", mockRolePermission); const res = await useCase.deleteRolePermission(req); expect(res.errorCode).toBeUndefined(); - expect(mockRolePermissionRepository.deleteRolePermission).toHaveBeenCalledWith(req); + expect( + mockRolePermissionRepository.deleteRolePermission, + ).toHaveBeenCalledWith(req); }); }); diff --git a/src/Domain/Role/UseCase/RolePermissionUseCase.ts b/src/Domain/Role/UseCase/RolePermissionUseCase.ts index 88fda48..8b8da35 100644 --- a/src/Domain/Role/UseCase/RolePermissionUseCase.ts +++ b/src/Domain/Role/UseCase/RolePermissionUseCase.ts @@ -1,12 +1,14 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { RolePermission } from "@src/Domain/Role/Entity/RolePermission"; -import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter"; -import { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import type { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; +import type { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter.js"; +import type { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository.js"; export class RolePermissionUseCase { - public constructor(private readonly rolePermissionRepository: IRolePermissionRepository) {} + public constructor( + private readonly rolePermissionRepository: IRolePermissionRepository, + ) {} public queryRolePermissions( request: RequestModel, @@ -20,7 +22,9 @@ export class RolePermissionUseCase { return this.rolePermissionRepository.createRolePermission(request); } - public deleteRolePermission(request: RequestModel): Promise> { + public deleteRolePermission( + request: RequestModel, + ): Promise> { return this.rolePermissionRepository.deleteRolePermission(request); } } diff --git a/src/Domain/Role/UseCase/RoleQueryUseCase.test.ts b/src/Domain/Role/UseCase/RoleQueryUseCase.test.ts index 32d7698..2d7973e 100644 --- a/src/Domain/Role/UseCase/RoleQueryUseCase.test.ts +++ b/src/Domain/Role/UseCase/RoleQueryUseCase.test.ts @@ -1,10 +1,10 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { RoleQueryUseCase } from "./RoleQueryUseCase"; -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter.js"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { RoleQueryUseCase } from "./RoleQueryUseCase.js"; describe("RoleQueryUseCase - Unit Tests", () => { let useCase: RoleQueryUseCase; @@ -18,7 +18,9 @@ describe("RoleQueryUseCase - Unit Tests", () => { test("should query roles", async () => { const mockFilter = new RoleFilter(1, "Admin"); const mockRoles = [new Role(1, "Admin")]; - const mockResponse = new ResponseModel("tx-1").withResponse(mockRoles); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockRoles, + ); mockRoleRepository.queryRoles.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", mockFilter); diff --git a/src/Domain/Role/UseCase/RoleQueryUseCase.ts b/src/Domain/Role/UseCase/RoleQueryUseCase.ts index b5c215d..55933d1 100644 --- a/src/Domain/Role/UseCase/RoleQueryUseCase.ts +++ b/src/Domain/Role/UseCase/RoleQueryUseCase.ts @@ -1,17 +1,21 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter"; -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter.js"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; export class RoleQueryUseCase { public constructor(private readonly roleRepository: IRoleRepository) {} - public queryRoles(request: RequestModel): Promise> { + public queryRoles( + request: RequestModel, + ): Promise> { return this.roleRepository.queryRoles(request); } - public queryById(request: RequestModel): Promise> { + public queryById( + request: RequestModel, + ): Promise> { return this.roleRepository.queryById(request); } } diff --git a/src/Domain/User/Entity/Email.test.ts b/src/Domain/User/Entity/Email.test.ts index a366cf2..3bcd659 100644 --- a/src/Domain/User/Entity/Email.test.ts +++ b/src/Domain/User/Entity/Email.test.ts @@ -1,4 +1,4 @@ -import { Email } from "./Email"; +import { Email } from "./Email.js"; describe("Email Value Object", () => { it("should create a valid email successfully and normalize it", () => { diff --git a/src/Domain/User/Entity/Password.test.ts b/src/Domain/User/Entity/Password.test.ts index 7009a09..17c63fc 100644 --- a/src/Domain/User/Entity/Password.test.ts +++ b/src/Domain/User/Entity/Password.test.ts @@ -1,4 +1,4 @@ -import { Password } from "./Password"; +import { Password } from "./Password.js"; describe("Password Value Object", () => { it("should create a valid password successfully", () => { @@ -22,6 +22,8 @@ describe("Password Value Object", () => { }); it("should throw an error for password too long", () => { - expect(() => new Password("SecurePass123!SecurePass123!")).toThrow(expectedError); + expect(() => new Password("SecurePass123!SecurePass123!")).toThrow( + expectedError, + ); }); }); diff --git a/src/Domain/User/Entity/PasswordUpdate.ts b/src/Domain/User/Entity/PasswordUpdate.ts index 62ba2fc..1fbab41 100644 --- a/src/Domain/User/Entity/PasswordUpdate.ts +++ b/src/Domain/User/Entity/PasswordUpdate.ts @@ -67,7 +67,9 @@ class PasswordUpdateBuilder { return this; } - public setPasswordConfirmation(passwordConfirmation: string): PasswordUpdateBuilder { + public setPasswordConfirmation( + passwordConfirmation: string, + ): PasswordUpdateBuilder { this.passwordConfirmation = passwordConfirmation; return this; } diff --git a/src/Domain/User/Entity/PersonalInformationUpdate.test.ts b/src/Domain/User/Entity/PersonalInformationUpdate.test.ts index 74c51a3..fb8d723 100644 --- a/src/Domain/User/Entity/PersonalInformationUpdate.test.ts +++ b/src/Domain/User/Entity/PersonalInformationUpdate.test.ts @@ -1,4 +1,4 @@ -import { PersonalInformationUpdate } from "./PersonalInformationUpdate"; +import { PersonalInformationUpdate } from "./PersonalInformationUpdate.js"; describe("PersonalInformationUpdate Entity - Unit Tests", () => { it("should build a PersonalInformationUpdate using constructor", () => { @@ -8,7 +8,9 @@ describe("PersonalInformationUpdate Entity - Unit Tests", () => { }); it("should build a PersonalInformationUpdate using builder", () => { - const builder = PersonalInformationUpdate.builder().setUserId("user-456").setCountryCode("US"); + const builder = PersonalInformationUpdate.builder() + .setUserId("user-456") + .setCountryCode("US"); expect(builder.getUserId()).toBe("user-456"); expect(builder.getCountryCode()).toBe("US"); diff --git a/src/Domain/User/Entity/PersonalInformationUpdate.ts b/src/Domain/User/Entity/PersonalInformationUpdate.ts index 0bc0457..35eda34 100644 --- a/src/Domain/User/Entity/PersonalInformationUpdate.ts +++ b/src/Domain/User/Entity/PersonalInformationUpdate.ts @@ -1,4 +1,4 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; export class PersonalInformationUpdate { private userId: string; @@ -21,8 +21,13 @@ export class PersonalInformationUpdate { return new PersonalInformationUpdateBuilder(); } - public static build(builder: PersonalInformationUpdateBuilder): PersonalInformationUpdate { - return new PersonalInformationUpdate(builder.getUserId(), builder.getCountryCode()); + public static build( + builder: PersonalInformationUpdateBuilder, + ): PersonalInformationUpdate { + return new PersonalInformationUpdate( + builder.getUserId(), + builder.getCountryCode(), + ); } } @@ -43,7 +48,9 @@ class PersonalInformationUpdateBuilder { return this.countryCode; } - public setCountryCode(countryCode: Nullable): PersonalInformationUpdateBuilder { + public setCountryCode( + countryCode: Nullable, + ): PersonalInformationUpdateBuilder { this.countryCode = countryCode; return this; } diff --git a/src/Domain/User/Entity/SessionInfoResponse.ts b/src/Domain/User/Entity/SessionInfoResponse.ts index b1895ab..0c7dbfc 100644 --- a/src/Domain/User/Entity/SessionInfoResponse.ts +++ b/src/Domain/User/Entity/SessionInfoResponse.ts @@ -1,4 +1,4 @@ -import { SessionUser } from "@variamosple/variamos-security"; +import type { SessionUser } from "@variamosple/variamos-security"; export interface SessionInfoResponse { user: SessionUser; diff --git a/src/Domain/User/Entity/User.test.ts b/src/Domain/User/Entity/User.test.ts index fe38cb3..a24ce64 100644 --- a/src/Domain/User/Entity/User.test.ts +++ b/src/Domain/User/Entity/User.test.ts @@ -1,4 +1,4 @@ -import { User } from "./User"; +import { User } from "./User.js"; describe("User Entity & Builder - Unit Tests", () => { test("should build a User successfully using builder and constructor", () => { diff --git a/src/Domain/User/Entity/User.ts b/src/Domain/User/Entity/User.ts index 7d91719..b9087d5 100644 --- a/src/Domain/User/Entity/User.ts +++ b/src/Domain/User/Entity/User.ts @@ -1,5 +1,5 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { Email } from "./Email"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { Email } from "./Email.js"; export class User { public id: Nullable; diff --git a/src/Domain/User/Entity/UserFilter.test.ts b/src/Domain/User/Entity/UserFilter.test.ts index 864abf3..d4544d5 100644 --- a/src/Domain/User/Entity/UserFilter.test.ts +++ b/src/Domain/User/Entity/UserFilter.test.ts @@ -1,8 +1,16 @@ -import { UserFilter } from "./UserFilter"; +import { UserFilter } from "./UserFilter.js"; describe("UserFilter Entity - Unit Tests", () => { it("should build UserFilter using constructor", () => { - const filter = new UserFilter("1", "user", "name", "email@test.com", "search", 1, 10); + const filter = new UserFilter( + "1", + "user", + "name", + "email@test.com", + "search", + 1, + 10, + ); expect(filter.id).toBe("1"); expect(filter.user).toBe("user"); expect(filter.name).toBe("name"); diff --git a/src/Domain/User/Entity/UserFilter.ts b/src/Domain/User/Entity/UserFilter.ts index f8e3b06..f9eff4e 100644 --- a/src/Domain/User/Entity/UserFilter.ts +++ b/src/Domain/User/Entity/UserFilter.ts @@ -1,5 +1,5 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class UserFilter extends PagedModel { public constructor( diff --git a/src/Domain/User/Entity/UserRegistration.ts b/src/Domain/User/Entity/UserRegistration.ts index 7b44843..577a196 100644 --- a/src/Domain/User/Entity/UserRegistration.ts +++ b/src/Domain/User/Entity/UserRegistration.ts @@ -1,6 +1,6 @@ -import { Credentials } from "./Credentials"; -import { Email } from "./Email"; -import { Password } from "./Password"; +import { Credentials } from "./Credentials.js"; +import { Email } from "./Email.js"; +import { Password } from "./Password.js"; export class UserRegistration extends Credentials { public name: string; @@ -13,12 +13,15 @@ export class UserRegistration extends Credentials { passwordConfirmation: string, ) { const validatedEmail = email instanceof Email ? email : new Email(email); - const validatedPassword = password instanceof Password ? password : new Password(password); + const validatedPassword = + password instanceof Password ? password : new Password(password); super(validatedEmail.getValue(), validatedPassword.getValue()); if (!name || name.trim() === "") { - throw new Error("Full name, Email and password, and password confirmation are required."); + throw new Error( + "Full name, Email and password, and password confirmation are required.", + ); } if (validatedPassword.getValue() !== passwordConfirmation) { throw new Error("Password and password confirmation do not match."); @@ -60,8 +63,15 @@ export class UserRegistrationBuilder { } public build(): UserRegistration { - if (!this.name || !this.email || !this.password || !this.passwordConfirmation) { - throw new Error("Full name, Email and password, and password confirmation are required."); + if ( + !this.name || + !this.email || + !this.password || + !this.passwordConfirmation + ) { + throw new Error( + "Full name, Email and password, and password confirmation are required.", + ); } const validatedEmail = new Email(this.email); const validatedPassword = new Password(this.password); diff --git a/src/Domain/User/Entity/UserRole.ts b/src/Domain/User/Entity/UserRole.ts index 7a65fc1..24653a8 100644 --- a/src/Domain/User/Entity/UserRole.ts +++ b/src/Domain/User/Entity/UserRole.ts @@ -1,4 +1,4 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; export class UserRole { public userId: Nullable; diff --git a/src/Domain/User/Entity/UserRoleFilter.ts b/src/Domain/User/Entity/UserRoleFilter.ts index 705da87..d75f91d 100644 --- a/src/Domain/User/Entity/UserRoleFilter.ts +++ b/src/Domain/User/Entity/UserRoleFilter.ts @@ -1,4 +1,4 @@ -import { PagedModel } from "@src/Domain/Core/Entity/PagedModel"; +import { PagedModel } from "@src/Domain/Core/Entity/PagedModel.js"; export class UserRoleFilter extends PagedModel { public constructor( @@ -14,7 +14,11 @@ export class UserRoleFilter extends PagedModel { } public static build(builder: UserRoleFilterBuilder): UserRoleFilter { - return new UserRoleFilter(builder.userId, builder.pageNumber, builder.pageSize); + return new UserRoleFilter( + builder.userId, + builder.pageNumber, + builder.pageSize, + ); } } diff --git a/src/Domain/User/IUserRepository.ts b/src/Domain/User/IUserRepository.ts index 2935d8c..a7df87b 100644 --- a/src/Domain/User/IUserRepository.ts +++ b/src/Domain/User/IUserRepository.ts @@ -1,11 +1,11 @@ -import { RequestModel } from "../Core/Entity/RequestModel"; -import { ResponseModel } from "../Core/Entity/ResponseModel"; -import { User } from "./Entity/User"; -import { UserFilter } from "./Entity/UserFilter"; -import { Credentials } from "./Entity/Credentials"; -import { UserRegistration } from "./Entity/UserRegistration"; -import { PasswordUpdate } from "./Entity/PasswordUpdate"; -import { PersonalInformationUpdate } from "./Entity/PersonalInformationUpdate"; +import type { RequestModel } from "../Core/Entity/RequestModel.js"; +import type { ResponseModel } from "../Core/Entity/ResponseModel.js"; +import type { Credentials } from "./Entity/Credentials.js"; +import type { PasswordUpdate } from "./Entity/PasswordUpdate.js"; +import type { PersonalInformationUpdate } from "./Entity/PersonalInformationUpdate.js"; +import type { User } from "./Entity/User.js"; +import type { UserFilter } from "./Entity/UserFilter.js"; +import type { UserRegistration } from "./Entity/UserRegistration.js"; export interface IUserRepository { queryUsers(request: RequestModel): Promise>; @@ -17,13 +17,19 @@ export interface IUserRepository { disableUser(request: RequestModel): Promise>; enableUser(request: RequestModel): Promise>; deleteUser(request: RequestModel): Promise>; - updateUserPassword(request: RequestModel): Promise>; + updateUserPassword( + request: RequestModel, + ): Promise>; updatePersonalInformation( request: RequestModel, ): Promise>; userExists(request: RequestModel): Promise>; getUserByEmail(email: string): Promise; - savePasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise; + savePasswordResetToken( + userId: string, + tokenHash: string, + expiresAt: Date, + ): Promise; getPasswordResetToken(tokenHash: string): Promise<{ userId: string; expiresAt: Date; diff --git a/src/Domain/User/Repository/IUserRoleRepository.ts b/src/Domain/User/Repository/IUserRoleRepository.ts index 0c94ff6..758c89e 100644 --- a/src/Domain/User/Repository/IUserRoleRepository.ts +++ b/src/Domain/User/Repository/IUserRoleRepository.ts @@ -1,12 +1,18 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { UserRole } from "../Entity/UserRole"; -import { UserRoleFilter } from "../Entity/UserRoleFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { UserRole } from "../Entity/UserRole.js"; +import type { UserRoleFilter } from "../Entity/UserRoleFilter.js"; export interface IUserRoleRepository { - queryUserRoles(request: RequestModel): Promise>; - queryUserRolesDetails(request: RequestModel): Promise>; - createUserRole(request: RequestModel): Promise>; + queryUserRoles( + request: RequestModel, + ): Promise>; + queryUserRolesDetails( + request: RequestModel, + ): Promise>; + createUserRole( + request: RequestModel, + ): Promise>; deleteUserRole(request: RequestModel): Promise>; } diff --git a/src/Domain/User/Service/PasswordResetTokenService.test.ts b/src/Domain/User/Service/PasswordResetTokenService.test.ts index 0e8d6f4..563ab73 100644 --- a/src/Domain/User/Service/PasswordResetTokenService.test.ts +++ b/src/Domain/User/Service/PasswordResetTokenService.test.ts @@ -1,8 +1,8 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { PasswordResetTokenService } from "./PasswordResetTokenService"; -import { IUserRepository } from "../IUserRepository"; -import { User } from "../Entity/User"; import logger from "jet-logger"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import type { User } from "../Entity/User.js"; +import type { IUserRepository } from "../IUserRepository.js"; +import { PasswordResetTokenService } from "./PasswordResetTokenService.js"; describe("PasswordResetTokenService", () => { let service: PasswordResetTokenService; @@ -30,7 +30,11 @@ describe("PasswordResetTokenService", () => { it("should generate a token and save its hash in the database successfully", async () => { mockUserRepository.savePasswordResetToken.mockResolvedValue(undefined); - const token = await service.createResetToken(mockUser, 3600000, "TEST CONTEXT"); + const token = await service.createResetToken( + mockUser, + 3600000, + "TEST CONTEXT", + ); expect(token).toBeDefined(); expect(token.length).toBe(36); // UUID length @@ -48,28 +52,36 @@ describe("PasswordResetTokenService", () => { it("should throw an error if user is disabled", async () => { const disabledUser = { ...mockUser, isEnabled: false } as User; - const loggerWarnSpy = jest.spyOn(logger, "warn").mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, "warn").mockImplementation(() => {}); - await expect(service.createResetToken(disabledUser, 3600000, "TEST CONTEXT")).rejects.toThrow( - "User account is disabled.", - ); + await expect( + service.createResetToken(disabledUser, 3600000, "TEST CONTEXT"), + ).rejects.toThrow("User account is disabled."); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("TEST CONTEXT")); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("user-123")); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("TEST CONTEXT"), + ); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("user-123"), + ); expect(mockUserRepository.savePasswordResetToken).not.toHaveBeenCalled(); loggerWarnSpy.mockRestore(); }); it("should throw an error if user is marked as deleted", async () => { const deletedUser = { ...mockUser, isDeleted: true } as User; - const loggerWarnSpy = jest.spyOn(logger, "warn").mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, "warn").mockImplementation(() => {}); - await expect(service.createResetToken(deletedUser, 3600000, "TEST CONTEXT")).rejects.toThrow( - "User account is deleted.", - ); + await expect( + service.createResetToken(deletedUser, 3600000, "TEST CONTEXT"), + ).rejects.toThrow("User account is deleted."); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("TEST CONTEXT")); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("user-123")); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("TEST CONTEXT"), + ); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("user-123"), + ); expect(mockUserRepository.savePasswordResetToken).not.toHaveBeenCalled(); loggerWarnSpy.mockRestore(); }); diff --git a/src/Domain/User/Service/PasswordResetTokenService.ts b/src/Domain/User/Service/PasswordResetTokenService.ts index f1ea5b3..06adb0d 100644 --- a/src/Domain/User/Service/PasswordResetTokenService.ts +++ b/src/Domain/User/Service/PasswordResetTokenService.ts @@ -1,8 +1,8 @@ -import { IUserRepository } from "../IUserRepository"; -import { User } from "../Entity/User"; -import { v4 as uuidv4 } from "uuid"; -import crypto from "crypto"; +import crypto from "node:crypto"; import logger from "jet-logger"; +import { v4 as uuidv4 } from "uuid"; +import type { User } from "../Entity/User.js"; +import type { IUserRepository } from "../IUserRepository.js"; export class PasswordResetTokenService { public constructor(private userRepository: IUserRepository) {} @@ -16,12 +16,16 @@ export class PasswordResetTokenService { auditContext: string, ): Promise { if (!user.isEnabled) { - logger.warn(`[${auditContext}] Failed: User account is disabled (ID: ${user.id}).`); + logger.warn( + `[${auditContext}] Failed: User account is disabled (ID: ${user.id}).`, + ); throw new Error("User account is disabled."); } if (user.isDeleted) { - logger.warn(`[${auditContext}] Failed: User account is marked as deleted (ID: ${user.id}).`); + logger.warn( + `[${auditContext}] Failed: User account is marked as deleted (ID: ${user.id}).`, + ); throw new Error("User account is deleted."); } @@ -29,7 +33,11 @@ export class PasswordResetTokenService { const expiresAt = new Date(Date.now() + expiryInMs); const tokenHash = crypto.createHash("sha256").update(token).digest("hex"); - await this.userRepository.savePasswordResetToken(user.id || "", tokenHash, expiresAt); + await this.userRepository.savePasswordResetToken( + user.id || "", + tokenHash, + expiresAt, + ); return token; } diff --git a/src/Domain/User/UseCase/UserAuthUseCase.test.ts b/src/Domain/User/UseCase/UserAuthUseCase.test.ts index bfd79bb..726b8eb 100644 --- a/src/Domain/User/UseCase/UserAuthUseCase.test.ts +++ b/src/Domain/User/UseCase/UserAuthUseCase.test.ts @@ -1,15 +1,15 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { UserAuthUseCase } from "./UserAuthUseCase"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration"; -import { Credentials } from "@src/Domain/User/Entity/Credentials"; -import { User } from "@src/Domain/User/Entity/User"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; +import { Credentials } from "@src/Domain/User/Entity/Credentials.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { UserAuthUseCase } from "./UserAuthUseCase.js"; describe("UserAuthUseCase", () => { let useCase: UserAuthUseCase; @@ -45,7 +45,9 @@ describe("UserAuthUseCase", () => { const req = new RequestModel("tx-1", reg); const res = await useCase.signUp(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); - expect(res.message).toBe("Password and password confirmation do not match."); + expect(res.message).toBe( + "Password and password confirmation do not match.", + ); }); it("should fail if password does not match complex regexp pattern", async () => { @@ -76,7 +78,9 @@ describe("UserAuthUseCase", () => { .setIsDeleted(false) .setCreatedAt(new Date()) .build(); - const mockResponse = new ResponseModel("tx-1").withResponse(mockUser); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockUser, + ); mockUserRepository.signUp.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", reg); @@ -97,7 +101,9 @@ describe("UserAuthUseCase", () => { .setIsDeleted(false) .setCreatedAt(new Date()) .build(); - const mockResponse = new ResponseModel("tx-1").withResponse(mockUser); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockUser, + ); mockUserRepository.signIn.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", credentials); @@ -119,7 +125,9 @@ describe("UserAuthUseCase", () => { .setIsDeleted(false) .setCreatedAt(new Date()) .build(); - const mockResponse = new ResponseModel("tx-1").withResponse(mockUser); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockUser, + ); mockUserRepository.findOrCreateUser.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", mockUser); @@ -132,8 +140,12 @@ describe("UserAuthUseCase", () => { describe("getGuestData", () => { it("should return Guest user details successfully", async () => { - const mockExistsResponse1 = new ResponseModel("tx-1").withResponse(true); - const mockExistsResponse2 = new ResponseModel("tx-1").withResponse(false); + const mockExistsResponse1 = new ResponseModel( + "tx-1", + ).withResponse(true); + const mockExistsResponse2 = new ResponseModel( + "tx-1", + ).withResponse(false); mockUserRepository.userExists .mockResolvedValueOnce(mockExistsResponse1) .mockResolvedValueOnce(mockExistsResponse2); diff --git a/src/Domain/User/UseCase/UserAuthUseCase.ts b/src/Domain/User/UseCase/UserAuthUseCase.ts index c75af20..721202d 100644 --- a/src/Domain/User/UseCase/UserAuthUseCase.ts +++ b/src/Domain/User/UseCase/UserAuthUseCase.ts @@ -1,11 +1,11 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository"; -import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration"; -import { Credentials } from "@src/Domain/User/Entity/Credentials"; -import { User } from "@src/Domain/User/Entity/User"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; +import type { Credentials } from "@src/Domain/User/Entity/Credentials.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; import { v4 as uuidv4 } from "uuid"; export class UserAuthUseCase { @@ -14,13 +14,17 @@ export class UserAuthUseCase { private readonly roleRepository: IGuestRoleRepository, ) {} - public async signUp(request: RequestModel): Promise> { + public async signUp( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); const data = request.data; try { if (!data) { - throw new Error("Full name, Email and password, and password confirmation are required."); + throw new Error( + "Full name, Email and password, and password confirmation are required.", + ); } UserRegistration.builder() .setName(data.name) @@ -29,21 +33,30 @@ export class UserAuthUseCase { .setPasswordConfirmation(data.passwordConfirmation) .build(); } catch (error) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, (error as Error).message); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ); } return this.userRepository.signUp(request); } - public async signIn(request: RequestModel): Promise> { + public async signIn( + request: RequestModel, + ): Promise> { return this.userRepository.signIn(request); } - public async findOrCreate(request: RequestModel): Promise> { + public async findOrCreate( + request: RequestModel, + ): Promise> { return this.userRepository.findOrCreateUser(request); } - public async getGuestData(request: RequestModel): Promise> { + public async getGuestData( + request: RequestModel, + ): Promise> { let guestId = request.data || uuidv4(); let userExists: boolean; const response = new ResponseModel(request.transactionId); diff --git a/src/Domain/User/UseCase/UserManagementUseCase.test.ts b/src/Domain/User/UseCase/UserManagementUseCase.test.ts index 5b8d1dd..f0b82a5 100644 --- a/src/Domain/User/UseCase/UserManagementUseCase.test.ts +++ b/src/Domain/User/UseCase/UserManagementUseCase.test.ts @@ -1,11 +1,11 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { UserManagementUseCase } from "./UserManagementUseCase"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate"; -import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate.js"; +import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { UserManagementUseCase } from "./UserManagementUseCase.js"; describe("UserManagementUseCase", () => { let useCase: UserManagementUseCase; @@ -18,7 +18,9 @@ describe("UserManagementUseCase", () => { describe("enable", () => { it("should enable user successfully", async () => { - mockUserRepository.enableUser.mockResolvedValue(new ResponseModel("tx-1")); + mockUserRepository.enableUser.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", "user-123"); const res = await useCase.enable(req); expect(res.errorCode).toBeUndefined(); @@ -28,7 +30,9 @@ describe("UserManagementUseCase", () => { describe("disable", () => { it("should disable user successfully", async () => { - mockUserRepository.disableUser.mockResolvedValue(new ResponseModel("tx-1")); + mockUserRepository.disableUser.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", "user-123"); const res = await useCase.disable(req); expect(res.errorCode).toBeUndefined(); @@ -38,7 +42,9 @@ describe("UserManagementUseCase", () => { describe("delete", () => { it("should delete user successfully", async () => { - mockUserRepository.deleteUser.mockResolvedValue(new ResponseModel("tx-1")); + mockUserRepository.deleteUser.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", "user-123"); const res = await useCase.delete(req); expect(res.errorCode).toBeUndefined(); @@ -57,7 +63,9 @@ describe("UserManagementUseCase", () => { const res = await useCase.updateProfile(req); expect(res.errorCode).toBeUndefined(); - expect(mockUserRepository.updatePersonalInformation).toHaveBeenCalledWith(req); + expect(mockUserRepository.updatePersonalInformation).toHaveBeenCalledWith( + req, + ); }); }); @@ -69,7 +77,9 @@ describe("UserManagementUseCase", () => { "NewPass123!", "NewPass123!", ); - mockUserRepository.updateUserPassword.mockResolvedValue(new ResponseModel("tx-1")); + mockUserRepository.updateUserPassword.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", mockUpdate); const res = await useCase.updatePassword(req); @@ -79,7 +89,12 @@ describe("UserManagementUseCase", () => { }); it("should fail to update password if missing fields", async () => { - const mockUpdate = new PasswordUpdate("user-123", "", "NewPass123!", "NewPass123!"); + const mockUpdate = new PasswordUpdate( + "user-123", + "", + "NewPass123!", + "NewPass123!", + ); const req = new RequestModel("tx-1", mockUpdate); const res = await useCase.updatePassword(req); @@ -100,11 +115,18 @@ describe("UserManagementUseCase", () => { const res = await useCase.updatePassword(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); - expect(res.message).toBe("New password and password confirmation do not match."); + expect(res.message).toBe( + "New password and password confirmation do not match.", + ); }); it("should fail to update password if new password is too simple", async () => { - const mockUpdate = new PasswordUpdate("user-123", "OldPass123!", "simple", "simple"); + const mockUpdate = new PasswordUpdate( + "user-123", + "OldPass123!", + "simple", + "simple", + ); const req = new RequestModel("tx-1", mockUpdate); const res = await useCase.updatePassword(req); diff --git a/src/Domain/User/UseCase/UserManagementUseCase.ts b/src/Domain/User/UseCase/UserManagementUseCase.ts index 5db9f84..9499a20 100644 --- a/src/Domain/User/UseCase/UserManagementUseCase.ts +++ b/src/Domain/User/UseCase/UserManagementUseCase.ts @@ -1,23 +1,29 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate"; -import { Password } from "@src/Domain/User/Entity/Password"; -import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Password } from "@src/Domain/User/Entity/Password.js"; +import type { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate.js"; +import type { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; export class UserManagementUseCase { public constructor(private readonly userRepository: IUserRepository) {} - public async enable(request: RequestModel): Promise> { + public async enable( + request: RequestModel, + ): Promise> { return this.userRepository.enableUser(request); } - public async disable(request: RequestModel): Promise> { + public async disable( + request: RequestModel, + ): Promise> { return this.userRepository.disableUser(request); } - public async delete(request: RequestModel): Promise> { + public async delete( + request: RequestModel, + ): Promise> { return this.userRepository.deleteUser(request); } @@ -27,7 +33,9 @@ export class UserManagementUseCase { return this.userRepository.updatePersonalInformation(request); } - public async updatePassword(request: RequestModel): Promise> { + public async updatePassword( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); const data = request.data; @@ -58,7 +66,10 @@ export class UserManagementUseCase { try { new Password(newPassword); } catch (error) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, (error as Error).message); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ); } return this.userRepository.updateUserPassword(request); diff --git a/src/Domain/User/UseCase/UserPasswordUseCase.test.ts b/src/Domain/User/UseCase/UserPasswordUseCase.test.ts index 0380e98..0bf8d50 100644 --- a/src/Domain/User/UseCase/UserPasswordUseCase.test.ts +++ b/src/Domain/User/UseCase/UserPasswordUseCase.test.ts @@ -1,13 +1,16 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { UserPasswordUseCase, UserPasswordUseCaseConfig } from "./UserPasswordUseCase"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IMailService } from "@src/Domain/Mail/IMailService"; -import { PasswordResetTokenService } from "@src/Domain/User/Service/PasswordResetTokenService"; -import { User } from "@src/Domain/User/Entity/User"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import type { User } from "@src/Domain/User/Entity/User.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { PasswordResetTokenService } from "@src/Domain/User/Service/PasswordResetTokenService.js"; import logger from "jet-logger"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { + UserPasswordUseCase, + type UserPasswordUseCaseConfig, +} from "./UserPasswordUseCase.js"; describe("UserPasswordUseCase", () => { let useCase: UserPasswordUseCase; @@ -36,7 +39,11 @@ describe("UserPasswordUseCase", () => { beforeEach(() => { mockUserRepository = mock(); mockMailService = mock(); - useCase = new UserPasswordUseCase(mockUserRepository, mockMailService, mockConfig); + useCase = new UserPasswordUseCase( + mockUserRepository, + mockMailService, + mockConfig, + ); }); describe("requestReset", () => { @@ -51,7 +58,9 @@ describe("UserPasswordUseCase", () => { const res = await useCase.requestReset(req); expect(res.errorCode).toBeUndefined(); - expect(mockUserRepository.getUserByEmail).toHaveBeenCalledWith("user@example.com"); + expect(mockUserRepository.getUserByEmail).toHaveBeenCalledWith( + "user@example.com", + ); expect(createTokenSpy).toHaveBeenCalledWith( mockUser, mockConfig.passwordResetExpiryInMs, @@ -66,7 +75,10 @@ describe("UserPasswordUseCase", () => { it("should return empty response if user is not found", async () => { mockUserRepository.getUserByEmail.mockResolvedValue(null); - const createTokenSpy = jest.spyOn(PasswordResetTokenService.prototype, "createResetToken"); + const createTokenSpy = vi.spyOn( + PasswordResetTokenService.prototype, + "createResetToken", + ); const req = new RequestModel("tx-1", "nonexistent@example.com"); const res = await useCase.requestReset(req); @@ -102,7 +114,9 @@ describe("UserPasswordUseCase", () => { const res = await useCase.requestReset(req); expect(res.errorCode).toBe(DomainErrorCodes.SYSTEM_ERROR); - expect(res.message).toBe("Failed to send recovery email. Please try again later."); + expect(res.message).toBe( + "Failed to send recovery email. Please try again later.", + ); createTokenSpy.mockRestore(); }); }); @@ -171,13 +185,20 @@ describe("UserPasswordUseCase", () => { expiresAt: tomorrow, usedAt: null, }); - mockUserRepository.resetPasswordAndUpdateToken.mockResolvedValue(undefined); + mockUserRepository.resetPasswordAndUpdateToken.mockResolvedValue( + undefined, + ); - const req = new RequestModel("tx-1", { token: "token-123", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "token-123", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBeUndefined(); - expect(mockUserRepository.resetPasswordAndUpdateToken).toHaveBeenCalledWith( + expect( + mockUserRepository.resetPasswordAndUpdateToken, + ).toHaveBeenCalledWith( "user-123", "NewPassword123!", "034192845dc489deca291f9f5ae0bb8e5472c991020bf64b3ebc6dec5a1d7e47", @@ -187,11 +208,16 @@ describe("UserPasswordUseCase", () => { it("should return verification error if token is invalid", async () => { mockUserRepository.getPasswordResetToken.mockResolvedValue(null); - const req = new RequestModel("tx-1", { token: "expired-token", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "expired-token", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); - expect(mockUserRepository.resetPasswordAndUpdateToken).not.toHaveBeenCalled(); + expect( + mockUserRepository.resetPasswordAndUpdateToken, + ).not.toHaveBeenCalled(); }); it("should return verification error if token is already used", async () => { @@ -201,12 +227,17 @@ describe("UserPasswordUseCase", () => { usedAt: new Date(), }); - const req = new RequestModel("tx-1", { token: "used-token", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "used-token", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); expect(res.message).toBe("Token already used."); - expect(mockUserRepository.resetPasswordAndUpdateToken).not.toHaveBeenCalled(); + expect( + mockUserRepository.resetPasswordAndUpdateToken, + ).not.toHaveBeenCalled(); }); it("should return SYSTEM_ERROR if resetPasswordAndUpdateToken throws a general error", async () => { @@ -220,7 +251,10 @@ describe("UserPasswordUseCase", () => { new Error("Database connection lost"), ); - const req = new RequestModel("tx-1", { token: "token-123", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "token-123", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBe(DomainErrorCodes.SYSTEM_ERROR); @@ -236,9 +270,14 @@ describe("UserPasswordUseCase", () => { const createTokenSpy = jest .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockResolvedValue("generated-token"); - const loggerInfoSpy = jest.spyOn(logger, "info").mockImplementation(() => {}); + const loggerInfoSpy = vi + .spyOn(logger, "info") + .mockImplementation(() => {}); - const req = new RequestModel("tx-1", { userId: "user-123", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "user-123", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBeUndefined(); @@ -251,8 +290,12 @@ describe("UserPasswordUseCase", () => { mockConfig.passwordResetExpiryInMs, "ADMIN PASSWORD RESET ATTEMPT", ); - expect(loggerInfoSpy).toHaveBeenCalledWith(expect.stringContaining("admin-456")); - expect(loggerInfoSpy).toHaveBeenCalledWith(expect.stringContaining("user-123")); + expect(loggerInfoSpy).toHaveBeenCalledWith( + expect.stringContaining("admin-456"), + ); + expect(loggerInfoSpy).toHaveBeenCalledWith( + expect.stringContaining("user-123"), + ); createTokenSpy.mockRestore(); loggerInfoSpy.mockRestore(); }); @@ -261,17 +304,29 @@ describe("UserPasswordUseCase", () => { mockUserRepository.queryById.mockResolvedValue( new ResponseModel("tx-1").withResponse(null), ); - const createTokenSpy = jest.spyOn(PasswordResetTokenService.prototype, "createResetToken"); - const loggerWarnSpy = jest.spyOn(logger, "warn").mockImplementation(() => {}); + const createTokenSpy = vi.spyOn( + PasswordResetTokenService.prototype, + "createResetToken", + ); + const loggerWarnSpy = vi + .spyOn(logger, "warn") + .mockImplementation(() => {}); - const req = new RequestModel("tx-1", { userId: "user-123", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "user-123", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBeUndefined(); expect(res.data).toBeUndefined(); expect(createTokenSpy).not.toHaveBeenCalled(); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("admin-456")); - expect(loggerWarnSpy).toHaveBeenCalledWith(expect.stringContaining("user-123")); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("admin-456"), + ); + expect(loggerWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("user-123"), + ); createTokenSpy.mockRestore(); loggerWarnSpy.mockRestore(); }); @@ -284,7 +339,10 @@ describe("UserPasswordUseCase", () => { .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("User account is disabled.")); - const req = new RequestModel("tx-1", { userId: "user-123", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "user-123", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBeUndefined(); @@ -293,7 +351,10 @@ describe("UserPasswordUseCase", () => { }); it("should return INVALID_INPUT if request parameters are missing", async () => { - const req = new RequestModel("tx-1", { userId: "", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); expect(res.message).toBe("User ID and Admin ID are required."); @@ -301,10 +362,16 @@ describe("UserPasswordUseCase", () => { it("should return error if queryById returns error response", async () => { mockUserRepository.queryById.mockResolvedValue( - new ResponseModel("tx-1").withError(DomainErrorCodes.SYSTEM_ERROR, "DB Error"), + new ResponseModel("tx-1").withError( + DomainErrorCodes.SYSTEM_ERROR, + "DB Error", + ), ); - const req = new RequestModel("tx-1", { userId: "user-123", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "user-123", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBe(DomainErrorCodes.SYSTEM_ERROR); @@ -319,7 +386,10 @@ describe("UserPasswordUseCase", () => { .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("Unexpected token creation issue")); - const req = new RequestModel("tx-1", { userId: "user-123", adminId: "admin-456" }); + const req = new RequestModel("tx-1", { + userId: "user-123", + adminId: "admin-456", + }); const res = await useCase.generateLink(req); expect(res.errorCode).toBe(DomainErrorCodes.SYSTEM_ERROR); @@ -358,7 +428,9 @@ describe("UserPasswordUseCase", () => { }); it("should catch errors in verifyToken and return SYSTEM_ERROR", async () => { - mockUserRepository.getPasswordResetToken.mockRejectedValue(new Error("DB error")); + mockUserRepository.getPasswordResetToken.mockRejectedValue( + new Error("DB error"), + ); const req = new RequestModel("tx-1", "token-abc"); const res = await useCase.verifyToken(req); expect(res.errorCode).toBe(DomainErrorCodes.SYSTEM_ERROR); @@ -383,7 +455,10 @@ describe("UserPasswordUseCase", () => { }) .mockResolvedValueOnce(null); - const req = new RequestModel("tx-1", { token: "token-123", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "token-123", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); @@ -401,11 +476,16 @@ describe("UserPasswordUseCase", () => { new Error("New password cannot be the same as the old password"), ); - const req = new RequestModel("tx-1", { token: "token-123", password: "NewPassword123!" }); + const req = new RequestModel("tx-1", { + token: "token-123", + password: "NewPassword123!", + }); const res = await useCase.resetPassword(req); expect(res.errorCode).toBe(DomainErrorCodes.INVALID_INPUT); - expect(res.message).toBe("New password cannot be the same as the old password"); + expect(res.message).toBe( + "New password cannot be the same as the old password", + ); }); }); }); diff --git a/src/Domain/User/UseCase/UserPasswordUseCase.ts b/src/Domain/User/UseCase/UserPasswordUseCase.ts index 59b92df..40e1933 100644 --- a/src/Domain/User/UseCase/UserPasswordUseCase.ts +++ b/src/Domain/User/UseCase/UserPasswordUseCase.ts @@ -1,10 +1,10 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IMailService } from "@src/Domain/Mail/IMailService"; -import { PasswordResetTokenService } from "@src/Domain/User/Service/PasswordResetTokenService"; -import crypto from "crypto"; +import crypto from "node:crypto"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { PasswordResetTokenService } from "@src/Domain/User/Service/PasswordResetTokenService.js"; import logger from "jet-logger"; export interface UserPasswordUseCaseConfig { @@ -23,12 +23,17 @@ export class UserPasswordUseCase { this.tokenService = new PasswordResetTokenService(userRepository); } - public async requestReset(request: RequestModel): Promise> { + public async requestReset( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const email = request.data || ""; if (!email) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Email is required."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Email is required.", + ); } const user = await this.userRepository.getUserByEmail(email); @@ -54,7 +59,10 @@ export class UserPasswordUseCase { } const recoveryLink = `${this.config.adminHomeUri}/#/reset-password?token=${token}`; - const emailSent = await this.mailService.sendPasswordResetMail(email, recoveryLink); + const emailSent = await this.mailService.sendPasswordResetMail( + email, + recoveryLink, + ); if (!emailSent) { return response.withErrorPromise( DomainErrorCodes.SYSTEM_ERROR, @@ -72,27 +80,42 @@ export class UserPasswordUseCase { } } - public async verifyToken(request: RequestModel): Promise> { + public async verifyToken( + request: RequestModel, + ): Promise> { const response = new ResponseModel(request.transactionId); try { const token = request.data || ""; if (!token) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Token is required."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Token is required.", + ); } const tokenHash = crypto.createHash("sha256").update(token).digest("hex"); - const dbToken = await this.userRepository.getPasswordResetToken(tokenHash); + const dbToken = + await this.userRepository.getPasswordResetToken(tokenHash); if (!dbToken) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Invalid token."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Invalid token.", + ); } if (dbToken.usedAt) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Token already used."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Token already used.", + ); } if (new Date() > new Date(dbToken.expiresAt)) { - return response.withError(DomainErrorCodes.INVALID_INPUT, "Token expired."); + return response.withError( + DomainErrorCodes.INVALID_INPUT, + "Token expired.", + ); } return response; @@ -123,40 +146,67 @@ export class UserPasswordUseCase { } // Verify token validity - const verifyRequest = new RequestModel(request.transactionId, token); + const verifyRequest = new RequestModel( + request.transactionId, + token, + ); const verifyRes = await this.verifyToken(verifyRequest); if (verifyRes.errorCode) { - return response.withError(verifyRes.errorCode, verifyRes.message || "Invalid token."); + return response.withError( + verifyRes.errorCode, + verifyRes.message || "Invalid token.", + ); } const tokenHash = crypto.createHash("sha256").update(token).digest("hex"); - const dbToken = await this.userRepository.getPasswordResetToken(tokenHash); + const dbToken = + await this.userRepository.getPasswordResetToken(tokenHash); if (!dbToken) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, "Invalid token."); + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + "Invalid token.", + ); } const userId = dbToken.userId; // Reset password in repository - await this.userRepository.resetPasswordAndUpdateToken(userId, password, tokenHash); + await this.userRepository.resetPasswordAndUpdateToken( + userId, + password, + tokenHash, + ); return response; } catch (error) { logger.err("Error resetting password:"); logger.err(error as Error); - const errorMessage = error instanceof Error ? error.message : "Error resetting password"; - if (errorMessage.includes("New password cannot be the same as the old password")) { - return response.withErrorPromise(DomainErrorCodes.INVALID_INPUT, errorMessage); + const errorMessage = + error instanceof Error ? error.message : "Error resetting password"; + if ( + errorMessage.includes( + "New password cannot be the same as the old password", + ) + ) { + return response.withErrorPromise( + DomainErrorCodes.INVALID_INPUT, + errorMessage, + ); } - return response.withErrorPromise(DomainErrorCodes.SYSTEM_ERROR, "Error resetting password"); + return response.withErrorPromise( + DomainErrorCodes.SYSTEM_ERROR, + "Error resetting password", + ); } } public async generateLink( request: RequestModel<{ userId: string; adminId: string }>, ): Promise> { - const response = new ResponseModel<{ recoveryUrl: string }>(request.transactionId); + const response = new ResponseModel<{ recoveryUrl: string }>( + request.transactionId, + ); const { userId, adminId } = (request.data || {}) as Partial<{ userId: string; adminId: string; diff --git a/src/Domain/User/UseCase/UserQueryUseCase.test.ts b/src/Domain/User/UseCase/UserQueryUseCase.test.ts index ee5508e..3715ef8 100644 --- a/src/Domain/User/UseCase/UserQueryUseCase.test.ts +++ b/src/Domain/User/UseCase/UserQueryUseCase.test.ts @@ -1,10 +1,10 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { UserQueryUseCase } from "./UserQueryUseCase"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { User } from "@src/Domain/User/Entity/User"; -import { UserFilter } from "@src/Domain/User/Entity/UserFilter"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserFilter } from "@src/Domain/User/Entity/UserFilter.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { UserQueryUseCase } from "./UserQueryUseCase.js"; describe("UserQueryUseCase", () => { let useCase: UserQueryUseCase; @@ -28,7 +28,9 @@ describe("UserQueryUseCase", () => { describe("queryList", () => { it("should query users with filter", async () => { const mockFilter = new UserFilter("1", "testuser"); - const mockResponse = new ResponseModel("tx-1").withResponse([mockUser]); + const mockResponse = new ResponseModel("tx-1").withResponse([ + mockUser, + ]); mockUserRepository.queryUsers.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", mockFilter); @@ -41,7 +43,9 @@ describe("UserQueryUseCase", () => { describe("queryById", () => { it("should query user by id successfully", async () => { - const mockResponse = new ResponseModel("tx-1").withResponse(mockUser); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockUser, + ); mockUserRepository.queryById.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", "user-123"); @@ -54,7 +58,9 @@ describe("UserQueryUseCase", () => { describe("sessionUser", () => { it("should find session user successfully", async () => { - const mockResponse = new ResponseModel("tx-1").withResponse(mockUser); + const mockResponse = new ResponseModel("tx-1").withResponse( + mockUser, + ); mockUserRepository.findSessionUser.mockResolvedValue(mockResponse); const req = new RequestModel("tx-1", "session-token"); diff --git a/src/Domain/User/UseCase/UserQueryUseCase.ts b/src/Domain/User/UseCase/UserQueryUseCase.ts index 75f50b2..84e6f12 100644 --- a/src/Domain/User/UseCase/UserQueryUseCase.ts +++ b/src/Domain/User/UseCase/UserQueryUseCase.ts @@ -1,25 +1,33 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { User } from "@src/Domain/User/Entity/User"; -import { UserFilter } from "@src/Domain/User/Entity/UserFilter"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import type { UserFilter } from "@src/Domain/User/Entity/UserFilter.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; export class UserQueryUseCase { public constructor(private readonly userRepository: IUserRepository) {} - public async queryList(request: RequestModel): Promise> { + public async queryList( + request: RequestModel, + ): Promise> { return this.userRepository.queryUsers(request); } - public async queryById(request: RequestModel): Promise> { + public async queryById( + request: RequestModel, + ): Promise> { return this.userRepository.queryById(request); } - public async sessionUser(request: RequestModel): Promise> { + public async sessionUser( + request: RequestModel, + ): Promise> { return this.userRepository.findSessionUser(request); } - public async myAccount(request: RequestModel): Promise> { + public async myAccount( + request: RequestModel, + ): Promise> { return this.userRepository.queryById(request).then((response) => { if (response.data) { response.data = User.builder() diff --git a/src/Domain/User/UseCase/UserRoleUseCase.test.ts b/src/Domain/User/UseCase/UserRoleUseCase.test.ts index 1b9e44b..8639659 100644 --- a/src/Domain/User/UseCase/UserRoleUseCase.test.ts +++ b/src/Domain/User/UseCase/UserRoleUseCase.test.ts @@ -1,11 +1,11 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { UserRoleUseCase } from "./UserRoleUseCase"; -import { IUserRoleRepository } from "../Repository/IUserRoleRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { UserRole } from "../Entity/UserRole"; -import { UserRoleFilter } from "../Entity/UserRoleFilter"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "@src/Domain/Role/Entity/Role.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { UserRole } from "../Entity/UserRole.js"; +import { UserRoleFilter } from "../Entity/UserRoleFilter.js"; +import type { IUserRoleRepository } from "../Repository/IUserRoleRepository.js"; +import { UserRoleUseCase } from "./UserRoleUseCase.js"; describe("UserRoleUseCase", () => { let useCase: UserRoleUseCase; @@ -46,7 +46,9 @@ describe("UserRoleUseCase", () => { it("should delete user role", async () => { const mockUserRole = new UserRole("user-1", 1); - mockRepository.deleteUserRole.mockResolvedValue(new ResponseModel("tx-1")); + mockRepository.deleteUserRole.mockResolvedValue( + new ResponseModel("tx-1"), + ); const req = new RequestModel("tx-1", mockUserRole); const res = await useCase.deleteUserRole(req); expect(res.errorCode).toBeUndefined(); diff --git a/src/Domain/User/UseCase/UserRoleUseCase.ts b/src/Domain/User/UseCase/UserRoleUseCase.ts index d8e76f4..419b949 100644 --- a/src/Domain/User/UseCase/UserRoleUseCase.ts +++ b/src/Domain/User/UseCase/UserRoleUseCase.ts @@ -1,12 +1,14 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { UserRole } from "../Entity/UserRole"; -import { UserRoleFilter } from "../Entity/UserRoleFilter"; -import { IUserRoleRepository } from "../Repository/IUserRoleRepository"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Role } from "@src/Domain/Role/Entity/Role.js"; +import type { UserRole } from "../Entity/UserRole.js"; +import type { UserRoleFilter } from "../Entity/UserRoleFilter.js"; +import type { IUserRoleRepository } from "../Repository/IUserRoleRepository.js"; export class UserRoleUseCase { - public constructor(private readonly userRoleRepository: IUserRoleRepository) {} + public constructor( + private readonly userRoleRepository: IUserRoleRepository, + ) {} public async queryUserRoles( request: RequestModel, @@ -20,11 +22,15 @@ export class UserRoleUseCase { return this.userRoleRepository.queryUserRolesDetails(request); } - public async createUserRole(request: RequestModel): Promise> { + public async createUserRole( + request: RequestModel, + ): Promise> { return this.userRoleRepository.createUserRole(request); } - public async deleteUserRole(request: RequestModel): Promise> { + public async deleteUserRole( + request: RequestModel, + ): Promise> { return this.userRoleRepository.deleteUserRole(request); } } diff --git a/src/Domain/Validations/ValidationConstants.test.ts b/src/Domain/Validations/ValidationConstants.test.ts index 693efcd..81ec36e 100644 --- a/src/Domain/Validations/ValidationConstants.test.ts +++ b/src/Domain/Validations/ValidationConstants.test.ts @@ -1,4 +1,4 @@ -import { PASSWORD_REGEXP } from "./ValidationConstants"; +import { PASSWORD_REGEXP } from "./ValidationConstants.js"; describe("Validation Constants & Messages - Unit Tests", () => { describe("PASSWORD_REGEXP", () => { @@ -12,7 +12,7 @@ describe("Validation Constants & Messages - Unit Tests", () => { }); it("should reject passwords that are too long (> 24 chars)", () => { - expect(PASSWORD_REGEXP.test("A".repeat(25) + "a1!")).toBe(false); + expect(PASSWORD_REGEXP.test(`${"A".repeat(25)}a1!`)).toBe(false); }); it("should reject passwords missing a lowercase letter", () => { diff --git a/src/Domain/Validations/ValidationConstants.ts b/src/Domain/Validations/ValidationConstants.ts index 9d18b18..77af4e3 100644 --- a/src/Domain/Validations/ValidationConstants.ts +++ b/src/Domain/Validations/ValidationConstants.ts @@ -1 +1,3 @@ -export const PASSWORD_REGEXP = Object.freeze(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,24}$/); +export const PASSWORD_REGEXP = Object.freeze( + /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,24}$/, +); diff --git a/src/Domain/Visit/Entity/Visit.ts b/src/Domain/Visit/Entity/Visit.ts index 5b93294..b603fc3 100644 --- a/src/Domain/Visit/Entity/Visit.ts +++ b/src/Domain/Visit/Entity/Visit.ts @@ -1,11 +1,15 @@ -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; export class Visit { public pageId: string; public userId: string; public countryCode: Nullable; - public constructor(pageId: string, userId: string, countryCode?: Nullable) { + public constructor( + pageId: string, + userId: string, + countryCode?: Nullable, + ) { this.pageId = pageId; this.userId = userId; this.countryCode = countryCode || null; diff --git a/src/Domain/Visit/Repository/IVisitRepository.ts b/src/Domain/Visit/Repository/IVisitRepository.ts index 7ff01ac..e82bf72 100644 --- a/src/Domain/Visit/Repository/IVisitRepository.ts +++ b/src/Domain/Visit/Repository/IVisitRepository.ts @@ -1,6 +1,6 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Visit } from "../Entity/Visit"; +import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Visit } from "../Entity/Visit.js"; export interface IVisitRepository { registerVisit(request: RequestModel): Promise>; diff --git a/src/Domain/Visit/UseCase/VisitUseCase.test.ts b/src/Domain/Visit/UseCase/VisitUseCase.test.ts index bf1d51d..9a767c0 100644 --- a/src/Domain/Visit/UseCase/VisitUseCase.test.ts +++ b/src/Domain/Visit/UseCase/VisitUseCase.test.ts @@ -1,11 +1,11 @@ -import { mock, MockProxy } from "jest-mock-extended"; -import { VisitUseCase } from "./VisitUseCase"; -import { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Visit } from "@src/Domain/Visit/Entity/Visit"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; +import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; +import type { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository.js"; +import { type MockProxy, mock } from "vitest-mock-extended"; +import { VisitUseCase } from "./VisitUseCase.js"; describe("VisitUseCase - Unit Tests", () => { let useCase: VisitUseCase; @@ -33,7 +33,9 @@ describe("VisitUseCase - Unit Tests", () => { DomainErrorCodes.SYSTEM_ERROR, "Database not responding", ); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockErrorResponse); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockErrorResponse, + ); const req = new RequestModel("tx-1", visit); const res = await useCase.registerVisit(req); @@ -45,11 +47,17 @@ describe("VisitUseCase - Unit Tests", () => { test("should register visit successfully using user country code", async () => { const visit = new Visit("home", "user-123"); - const mockCountryResponse = new ResponseModel("tx-1").withResponse("FR"); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockCountryResponse); + const mockCountryResponse = new ResponseModel("tx-1").withResponse( + "FR", + ); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockCountryResponse, + ); const mockSavedVisit = new Visit("home", "user-123", "FR"); - const mockRegisterResponse = new ResponseModel("tx-1").withResponse(mockSavedVisit); + const mockRegisterResponse = new ResponseModel("tx-1").withResponse( + mockSavedVisit, + ); mockVisitRepository.registerVisit.mockResolvedValue(mockRegisterResponse); const req = new RequestModel("tx-1", visit); @@ -65,14 +73,24 @@ describe("VisitUseCase - Unit Tests", () => { test("should fallback to IP country code when user country code is null and ipAddress is provided", async () => { const visit = new Visit("home", "user-123"); - const mockUserCountryResponse = new ResponseModel("tx-1").withResponse(null); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockUserCountryResponse); + const mockUserCountryResponse = new ResponseModel( + "tx-1", + ).withResponse(null); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockUserCountryResponse, + ); - const mockIpCountryResponse = new ResponseModel("tx-1").withResponse("US"); - mockCountriesRepository.getIpCountryCode.mockResolvedValue(mockIpCountryResponse); + const mockIpCountryResponse = new ResponseModel( + "tx-1", + ).withResponse("US"); + mockCountriesRepository.getIpCountryCode.mockResolvedValue( + mockIpCountryResponse, + ); const mockSavedVisit = new Visit("home", "user-123", "US"); - const mockRegisterResponse = new ResponseModel("tx-1").withResponse(mockSavedVisit); + const mockRegisterResponse = new ResponseModel("tx-1").withResponse( + mockSavedVisit, + ); mockVisitRepository.registerVisit.mockResolvedValue(mockRegisterResponse); const req = new RequestModel("tx-1", visit); @@ -90,7 +108,9 @@ describe("VisitUseCase - Unit Tests", () => { const mockErrorResponse = new ResponseModel("tx-1"); mockErrorResponse.errorCode = DomainErrorCodes.SYSTEM_ERROR; mockErrorResponse.message = undefined; - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockErrorResponse); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockErrorResponse, + ); const req = new RequestModel("tx-1", visit); const res = await useCase.registerVisit(req); @@ -101,14 +121,24 @@ describe("VisitUseCase - Unit Tests", () => { test("should fallback to null countryCode if ipCountryResponse has no data", async () => { const visit = new Visit("home", "user-123"); - const mockUserCountryResponse = new ResponseModel("tx-1").withResponse(null); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockUserCountryResponse); + const mockUserCountryResponse = new ResponseModel( + "tx-1", + ).withResponse(null); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockUserCountryResponse, + ); - const mockIpCountryResponse = new ResponseModel("tx-1").withResponse(null); - mockCountriesRepository.getIpCountryCode.mockResolvedValue(mockIpCountryResponse); + const mockIpCountryResponse = new ResponseModel( + "tx-1", + ).withResponse(null); + mockCountriesRepository.getIpCountryCode.mockResolvedValue( + mockIpCountryResponse, + ); const mockSavedVisit = new Visit("home", "user-123", null); - const mockRegisterResponse = new ResponseModel("tx-1").withResponse(mockSavedVisit); + const mockRegisterResponse = new ResponseModel("tx-1").withResponse( + mockSavedVisit, + ); mockVisitRepository.registerVisit.mockResolvedValue(mockRegisterResponse); const req = new RequestModel("tx-1", visit); @@ -120,11 +150,17 @@ describe("VisitUseCase - Unit Tests", () => { test("should not query IP country code if ipAddress is not provided", async () => { const visit = new Visit("home", "user-123"); - const mockUserCountryResponse = new ResponseModel("tx-1").withResponse(null); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockUserCountryResponse); + const mockUserCountryResponse = new ResponseModel( + "tx-1", + ).withResponse(null); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockUserCountryResponse, + ); const mockSavedVisit = new Visit("home", "user-123", null); - const mockRegisterResponse = new ResponseModel("tx-1").withResponse(mockSavedVisit); + const mockRegisterResponse = new ResponseModel("tx-1").withResponse( + mockSavedVisit, + ); mockVisitRepository.registerVisit.mockResolvedValue(mockRegisterResponse); const req = new RequestModel("tx-1", visit); @@ -136,8 +172,12 @@ describe("VisitUseCase - Unit Tests", () => { test("should fallback to null countryCode if ipCountryResponse is null", async () => { const visit = new Visit("home", "user-123"); - const mockUserCountryResponse = new ResponseModel("tx-1").withResponse(null); - mockCountriesRepository.getUserCountryCode.mockResolvedValue(mockUserCountryResponse); + const mockUserCountryResponse = new ResponseModel( + "tx-1", + ).withResponse(null); + mockCountriesRepository.getUserCountryCode.mockResolvedValue( + mockUserCountryResponse, + ); const getNullResponse = (): ResponseModel | null => null; mockCountriesRepository.getIpCountryCode.mockResolvedValue( @@ -145,7 +185,9 @@ describe("VisitUseCase - Unit Tests", () => { ); const mockSavedVisit = new Visit("home", "user-123", null); - const mockRegisterResponse = new ResponseModel("tx-1").withResponse(mockSavedVisit); + const mockRegisterResponse = new ResponseModel("tx-1").withResponse( + mockSavedVisit, + ); mockVisitRepository.registerVisit.mockResolvedValue(mockRegisterResponse); const req = new RequestModel("tx-1", visit); diff --git a/src/Domain/Visit/UseCase/VisitUseCase.ts b/src/Domain/Visit/UseCase/VisitUseCase.ts index dcbe77b..cdad1f7 100644 --- a/src/Domain/Visit/UseCase/VisitUseCase.ts +++ b/src/Domain/Visit/UseCase/VisitUseCase.ts @@ -1,9 +1,9 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Visit } from "@src/Domain/Visit/Entity/Visit"; -import { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; +import type { Visit } from "@src/Domain/Visit/Entity/Visit.js"; +import type { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository.js"; export class VisitUseCase { public constructor( @@ -22,9 +22,10 @@ export class VisitUseCase { ); } - const countryCodeResponse = await this.countriesRepository.getUserCountryCode( - new RequestModel(request.transactionId, request.data.userId), - ); + const countryCodeResponse = + await this.countriesRepository.getUserCountryCode( + new RequestModel(request.transactionId, request.data.userId), + ); if (countryCodeResponse.errorCode) { return new ResponseModel(request.transactionId).withError( diff --git a/src/EntryPoints/AuthRouter.test.ts b/src/EntryPoints/AuthRouter.test.ts index 66b5ae9..8323b01 100644 --- a/src/EntryPoints/AuthRouter.test.ts +++ b/src/EntryPoints/AuthRouter.test.ts @@ -1,5 +1,5 @@ // Mock google-auth-library as a standard class to bypass Jest resetMocks: true -jest.mock("google-auth-library", () => { +vi.mock("google-auth-library", () => { return { OAuth2Client: class { public verifyIdToken({ idToken }: { idToken: string }) { @@ -22,67 +22,76 @@ jest.mock("google-auth-library", () => { }; }); -jest.mock("./errorMapper", () => { - const actual = jest.requireActual("./errorMapper"); +vi.mock("./errorMapper", async () => { + const actual = + await vi.importActual( + "./errorMapper.js", + ); return { ...actual, - mapDomainErrorToHttpStatus: jest.fn(), + mapDomainErrorToHttpStatus: vi.fn(), }; }); -import express from "express"; -import logger from "jet-logger"; -import supertest from "supertest"; -import EnvVars from "@src/common/EnvVars"; -import cookieParser from "cookie-parser"; -import { createAuthRouter, AUTH_ROUTE } from "./AuthRouter"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; +import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; import { UserPasswordUseCase, - UserPasswordUseCaseConfig, -} from "@src/Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase"; -import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { User } from "@src/Domain/User/Entity/User"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; + type UserPasswordUseCaseConfig, +} from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { + ResponseModel as SecurityResponseModel, + type SessionInfo, + createJwt, getToken, - validateToken, + hasPermissions, isSessionExpired, sessionInfoToSessionUser, - createJwt, - SessionInfo, - ResponseModel as SecurityResponseModel, - hasPermissions, + validateToken, } from "@variamosple/variamos-security"; +import cookieParser from "cookie-parser"; +import express from "express"; +import logger from "jet-logger"; +import supertest from "supertest"; +import { AUTH_ROUTE, createAuthRouter } from "./AuthRouter.js"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IMailService } from "@src/Domain/Mail/IMailService"; -import { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository"; -import { mock } from "jest-mock-extended"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import { mock } from "vitest-mock-extended"; // Mock other dependencies -jest.mock("@src/Domain/User/UseCase/UserAuthUseCase"); -jest.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); -jest.mock("@src/Domain/User/UseCase/UserManagementUseCase"); -jest.mock("@src/Domain/User/UseCase/UserQueryUseCase"); -jest.mock("@variamosple/variamos-security", () => { - const actual = jest.requireActual("@variamosple/variamos-security"); +vi.mock("@src/Domain/User/UseCase/UserAuthUseCase"); +vi.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); +vi.mock("@src/Domain/User/UseCase/UserManagementUseCase"); +vi.mock("@src/Domain/User/UseCase/UserQueryUseCase"); +vi.mock("@variamosple/variamos-security", async () => { + const actual = await vi.importActual< + typeof import("@variamosple/variamos-security") + >("@variamosple/variamos-security"); return { ...actual, - getToken: jest.fn(), - validateToken: jest.fn(), - isSessionExpired: jest.fn(), - sessionInfoToSessionUser: jest.fn(), - createJwt: jest.fn(), - hasPermissions: jest + getToken: vi.fn(), + validateToken: vi.fn(), + isSessionExpired: vi.fn(), + sessionInfoToSessionUser: vi.fn(), + createJwt: vi.fn(), + hasPermissions: vi .fn() .mockImplementation( (_permissions?: string[], _roles?: string[]) => - (req: express.Request, _res: express.Response, next: express.NextFunction) => { + ( + req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { req.user = { id: "user-123", name: "John Doe", @@ -112,7 +121,10 @@ interface TestSessionApiResponse { } function parseCookies(response: supertest.Response): string[] { - const rawCookies = response.headers["set-cookie"] as string | string[] | undefined; + const rawCookies = response.headers["set-cookie"] as + | string + | string[] + | undefined; if (!rawCookies) { return []; } @@ -135,7 +147,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { mock(), mock(), ); - const mockUserManagementUseCase = new UserManagementUseCase(mock()); + const mockUserManagementUseCase = new UserManagementUseCase( + mock(), + ); const mockUserQueryUseCase = new UserQueryUseCase(mock()); app.use( AUTH_ROUTE, @@ -148,32 +162,35 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { ); }); - beforeEach(() => { - jest.clearAllMocks(); - const actualErrorMapper = jest.requireActual("./errorMapper"); - jest - .mocked(mapDomainErrorToHttpStatus) - .mockImplementation( - actualErrorMapper.mapDomainErrorToHttpStatus as typeof mapDomainErrorToHttpStatus, + beforeEach(async () => { + vi.clearAllMocks(); + const actualErrorMapper = + await vi.importActual( + "./errorMapper.js", ); + vi.mocked(mapDomainErrorToHttpStatus).mockImplementation( + actualErrorMapper.mapDomainErrorToHttpStatus as typeof mapDomainErrorToHttpStatus, + ); - jest - .mocked(hasPermissions) - .mockImplementation( - (_permissions?: string[], _roles?: string[]) => - (req: express.Request, _res: express.Response, next: express.NextFunction) => { - req.user = { - id: "user-123", - name: "John Doe", - email: "john@example.com", - user: "john", - roles: ["guest"], - permissions: ["my-account::query", "my-account::update"], - }; - next(); - return Promise.resolve(); - }, - ); + vi.mocked(hasPermissions).mockImplementation( + (_permissions?: string[], _roles?: string[]) => + ( + req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { + req.user = { + id: "user-123", + name: "John Doe", + email: "john@example.com", + user: "john", + roles: ["guest"], + permissions: ["my-account::query", "my-account::update"], + }; + next(); + return Promise.resolve(); + }, + ); }); describe("AUTH_ROUTE Constant", () => { @@ -200,10 +217,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app).get("/auth/session-info"); @@ -213,12 +230,11 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return error code if validationResponse has error", async () => { - const validationResponse = new SecurityResponseModel("getSessionInfo").withError( - HttpStatusCodes.UNAUTHORIZED, - "Invalid Token", - ); - jest.mocked(getToken).mockReturnValue("bad-token"); - jest.mocked(validateToken).mockResolvedValue(validationResponse); + const validationResponse = new SecurityResponseModel( + "getSessionInfo", + ).withError(HttpStatusCodes.UNAUTHORIZED, "Invalid Token"); + vi.mocked(getToken).mockReturnValue("bad-token"); + vi.mocked(validateToken).mockResolvedValue(validationResponse); const response = await supertest(app).get("/auth/session-info"); @@ -228,19 +244,25 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { it("should return 401 if session is expired", async () => { const mockToken = "expired-token"; - const mockUserPayload = { sub: "user-123", exp: 1000, iat: 1000 } as SessionInfo; + const mockUserPayload = { + sub: "user-123", + exp: 1000, + iat: 1000, + } as SessionInfo; const validationResponse = new SecurityResponseModel( "getSessionInfo", ).withResponse(mockUserPayload); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.UNAUTHORIZED); - expect(response.body.message).toBe("Your session has expired, please log in again."); + expect(response.body.message).toBe( + "Your session has expired, please log in again.", + ); }); it("should return 401 if user is missing iat during expired check", async () => { @@ -249,9 +271,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { "getSessionInfo", ).withResponse(mockUserPayload); - jest.mocked(getToken).mockReturnValue("expired-token-no-iat"); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(getToken).mockReturnValue("expired-token-no-iat"); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); const response = await supertest(app).get("/auth/session-info"); @@ -259,7 +281,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 401 when session-info logic throws an exception (AuthRouter handles this as 401)", async () => { - jest.mocked(getToken).mockImplementation(() => { + vi.mocked(getToken).mockImplementation(() => { throw new Error("Unexpected error"); }); @@ -293,10 +315,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app) .get("/auth/session-info") @@ -308,9 +330,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(redirectToCookie).toBeDefined(); expect(redirectToCookie?.includes("redirectTo=;")).toBe(true); expect( - redirectToCookie?.includes("Max-Age=0") || !redirectToCookie?.includes("Max-Age="), + redirectToCookie?.includes("Max-Age=0") || + !redirectToCookie?.includes("Max-Age="), + ).toBe(true); + expect( + cookies.some( + (c) => c.includes("SameSite=None") && c.includes("Secure"), + ), ).toBe(true); - expect(cookies.some((c) => c.includes("SameSite=None") && c.includes("Secure"))).toBe(true); // Restore AllowedOrigins Object.defineProperty(EnvVars.CORS, "AllowedOriginsPatterns", { @@ -337,17 +364,19 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app) .get("/auth/session-info") .set("Cookie", ["redirectTo=data:text/html,Hello"]); expect(response.status).toBe(HttpStatusCodes.OK); - const body = response.body as TestSessionApiResponse & { data: { redirect?: string } }; + const body = response.body as TestSessionApiResponse & { + data: { redirect?: string }; + }; expect(body.data.redirect).toBe("data:text/html,Hello"); }); @@ -368,17 +397,19 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app) .get("/auth/session-info") .set("Cookie", ["redirectTo=not-a-valid-url"]); expect(response.status).toBe(HttpStatusCodes.OK); - const body = response.body as TestSessionApiResponse & { data: { redirect?: string } }; + const body = response.body as TestSessionApiResponse & { + data: { redirect?: string }; + }; expect(body.data.redirect).toBeUndefined(); }); @@ -402,10 +433,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setPermissions([]) .build(); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue( + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( new ResponseModel("getSessionInfo").withResponse(mockDomainUser), ); @@ -432,10 +463,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app) .get("/auth/session-info") @@ -460,23 +491,29 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { user: "john", email: "john@example.com", }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("John Doe").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue(refreshedResponse); - jest.mocked(createJwt).mockResolvedValue("new-jwt-token"); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( + refreshedResponse, + ); + vi.mocked(createJwt).mockResolvedValue("new-jwt-token"); const response = await supertest(app) .get("/auth/session-info") .set("Cookie", ["redirectTo=http://localhost:3000/dashboard"]); expect(response.status).toBe(HttpStatusCodes.OK); - const body = response.body as { data: { redirect: string; authToken?: string } }; + const body = response.body as { + data: { redirect: string; authToken?: string }; + }; expect(body.data.redirect).toBe("http://localhost:3000/dashboard"); // Local redirects must NOT expose the authToken in the body expect(body.data.authToken).toBeUndefined(); @@ -507,15 +544,19 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "guest@example.com", roles: ["guest"], }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("Guest User").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(refreshedResponse); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + refreshedResponse, + ); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.OK); @@ -544,11 +585,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { "Expired", ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(refreshedResponse); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + refreshedResponse, + ); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.UNAUTHORIZED); @@ -572,15 +615,19 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "admin@example.com", roles: ["admin"], }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("Admin User").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue(refreshedResponse); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( + refreshedResponse, + ); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.OK); @@ -611,16 +658,20 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "admin@example.com", roles: ["admin"], }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("Admin User").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue(refreshedResponse); - jest.mocked(createJwt).mockResolvedValue("new-refreshed-jwt-token"); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( + refreshedResponse, + ); + vi.mocked(createJwt).mockResolvedValue("new-refreshed-jwt-token"); const response = await supertest(app) .get("/auth/session-info") @@ -640,11 +691,18 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("POST /auth/sign-in", () => { it("should return 200 and set cookie on successful sign in", async () => { - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockResolvedValue(expectedResponse); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); + (UserAuthUseCase.prototype.signIn as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/sign-in") @@ -657,7 +715,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { const cookies = parseCookies(response); // Default SameSite must be Strict, and Max-Age/Expires must be present (maxAge = true) expect(cookies.some((c) => c.includes("SameSite=Strict"))).toBe(true); - expect(cookies.some((c) => c.includes("Max-Age=") || c.includes("Expires="))).toBe(true); + expect( + cookies.some((c) => c.includes("Max-Age=") || c.includes("Expires=")), + ).toBe(true); expect(cookies.some((c) => c.includes("Domain=localhost"))).toBe(true); expect(cookies.some((c) => c.includes("HttpOnly"))).toBe(true); }); @@ -667,7 +727,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.UNAUTHORIZED_ACCESS, "Invalid credentials", ); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signIn as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/sign-in") @@ -683,11 +745,18 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { configurable: true, }); - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockResolvedValue(expectedResponse); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); + (UserAuthUseCase.prototype.signIn as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/sign-in") @@ -696,7 +765,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(response.status).toBe(HttpStatusCodes.OK); const body = response.body as { data: { redirect: string } }; - expect(body.data.redirect).toBe("http://allowed-origin.com/dashboard?authToken=jwt-token"); + expect(body.data.redirect).toBe( + "http://allowed-origin.com/dashboard?authToken=jwt-token", + ); Object.defineProperty(EnvVars.CORS, "AllowedOriginsPatterns", { value: originalPatterns, @@ -730,7 +801,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when sign-in throws an exception", async () => { - (UserAuthUseCase.prototype.signIn as jest.Mock).mockRejectedValue( + (UserAuthUseCase.prototype.signIn as vi.Mock).mockRejectedValue( new Error("Unexpected sign-in error"), ); @@ -745,10 +816,17 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("POST /auth/sign-up", () => { it("should return 200 on successful sign up", async () => { - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signUp").withResponse(mockUser); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signUp").withResponse( + mockUser, + ); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/auth/sign-up").send({ name: "John Doe", @@ -766,7 +844,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.DUPLICATE_ENTITY, "User already exists", ); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/auth/sign-up").send({ name: "John Doe", @@ -783,7 +863,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Passwords do not match", ); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/auth/sign-up").send({ name: "John Doe", @@ -800,7 +882,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Invalid name", ); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/auth/sign-up").send({ name: "", @@ -813,7 +897,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when sign-up throws an exception", async () => { - (UserAuthUseCase.prototype.signUp as jest.Mock).mockRejectedValue( + (UserAuthUseCase.prototype.signUp as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -840,11 +924,18 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("POST /auth/guest/sign-in", () => { it("should return 200 and set cookie on guest sign in", async () => { - const mockUser = User.builder().setId("guest-123").setName("Guest").build(); - const expectedResponse = new ResponseModel("signInAsGuest").withResponse(mockUser); + const mockUser = User.builder() + .setId("guest-123") + .setName("Guest") + .build(); + const expectedResponse = new ResponseModel("signInAsGuest").withResponse( + mockUser, + ); - jest.mocked(createJwt).mockResolvedValue("guest-jwt-token"); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(expectedResponse); + vi.mocked(createJwt).mockResolvedValue("guest-jwt-token"); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/guest/sign-in") @@ -859,7 +950,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Invalid guest id", ); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/guest/sign-in") @@ -869,7 +962,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when guest sign-in throws an exception", async () => { - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockRejectedValue( + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -887,11 +980,18 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { configurable: true, }); - const mockUser = User.builder().setId("guest-123").setName("Guest").build(); - const expectedResponse = new ResponseModel("signInAsGuest").withResponse(mockUser); + const mockUser = User.builder() + .setId("guest-123") + .setName("Guest") + .build(); + const expectedResponse = new ResponseModel("signInAsGuest").withResponse( + mockUser, + ); - jest.mocked(createJwt).mockResolvedValue("guest-jwt-token"); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(expectedResponse); + vi.mocked(createJwt).mockResolvedValue("guest-jwt-token"); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/guest/sign-in") @@ -913,9 +1013,16 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("GET /auth/my-account", () => { it("should return 200 on successful fetch", async () => { - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("myAccount").withResponse(mockUser); - (UserQueryUseCase.prototype.myAccount as jest.Mock).mockResolvedValue(expectedResponse); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("myAccount").withResponse( + mockUser, + ); + (UserQueryUseCase.prototype.myAccount as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/auth/my-account"); @@ -923,7 +1030,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when getMyAccount throws an exception", async () => { - (UserQueryUseCase.prototype.myAccount as jest.Mock).mockRejectedValue( + (UserQueryUseCase.prototype.myAccount as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -935,10 +1042,12 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("PUT /auth/my-account/information", () => { it("should return 200 on successful update", async () => { - const expectedResponse = new ResponseModel("updateMyAccountInformation").withResponse(null); - (UserManagementUseCase.prototype.updateProfile as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "updateMyAccountInformation", + ).withResponse(null); + ( + UserManagementUseCase.prototype.updateProfile as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .put("/auth/my-account/information") @@ -948,9 +1057,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when updatePersonalInformation throws an exception", async () => { - (UserManagementUseCase.prototype.updateProfile as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + UserManagementUseCase.prototype.updateProfile as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app) .put("/auth/my-account/information") @@ -962,12 +1071,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { describe("PUT /auth/password-update", () => { it("should return 200 on successful password update", async () => { - const expectedResponse = new ResponseModel("passwordUpdate").withResponse(null); - - (UserManagementUseCase.prototype.updatePassword as jest.Mock).mockResolvedValue( - expectedResponse, + const expectedResponse = new ResponseModel("passwordUpdate").withResponse( + null, ); + ( + UserManagementUseCase.prototype.updatePassword as vi.Mock + ).mockResolvedValue(expectedResponse); + const response = await supertest(app).put("/auth/password-update").send({ currentPassword: "OldPassword123!", newPassword: "NewPassword123!", @@ -982,9 +1093,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Invalid password", ); - (UserManagementUseCase.prototype.updatePassword as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + UserManagementUseCase.prototype.updatePassword as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).put("/auth/password-update").send({ currentPassword: "OldPassword123!", @@ -996,9 +1107,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when updatePassword throws an exception", async () => { - (UserManagementUseCase.prototype.updatePassword as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + UserManagementUseCase.prototype.updatePassword as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).put("/auth/password-update").send({ currentPassword: "OldPassword123!", @@ -1017,9 +1128,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setName("John Doe") .setEmail("john@example.com") .build(); - const expectedResponse = new ResponseModel("loginWithGoogle").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("google-jwt-token"); - (UserAuthUseCase.prototype.findOrCreate as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel( + "loginWithGoogle", + ).withResponse(mockUser); + vi.mocked(createJwt).mockResolvedValue("google-jwt-token"); + (UserAuthUseCase.prototype.findOrCreate as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/google/callback") @@ -1034,14 +1149,18 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Creation failed", ); - (UserAuthUseCase.prototype.findOrCreate as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.findOrCreate as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/google/callback") .send({ credential: "mock-google-id-token" }); expect(response.status).toBe(302); - expect(response.headers.location).toContain("errorMessage=Creation%20failed"); + expect(response.headers.location).toContain( + "errorMessage=Creation%20failed", + ); }); it("should redirect to login if ticket verification throws an exception", async () => { @@ -1074,9 +1193,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setName("John Doe") .setEmail("john@example.com") .build(); - const expectedResponse = new ResponseModel("loginWithGoogle").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("google-jwt-token"); - (UserAuthUseCase.prototype.findOrCreate as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel( + "loginWithGoogle", + ).withResponse(mockUser); + vi.mocked(createJwt).mockResolvedValue("google-jwt-token"); + (UserAuthUseCase.prototype.findOrCreate as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/google/callback") @@ -1104,7 +1227,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { undefined, "Password reset email sent", ).withResponse(null); - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/forgot-password") @@ -1119,7 +1244,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Email not found", ); - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/forgot-password") @@ -1129,7 +1256,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when forgot-password throws an exception", async () => { - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockRejectedValue( + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -1148,7 +1275,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { undefined, "Token verified", ).withResponse(null); - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .get("/auth/verify-token") @@ -1163,7 +1292,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Token expired", ); - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .get("/auth/verify-token") @@ -1173,11 +1304,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when verify-token throws an exception", async () => { - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockRejectedValue( + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).get("/auth/verify-token").query({ token: "token" }); + const response = await supertest(app) + .get("/auth/verify-token") + .query({ token: "token" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); @@ -1190,9 +1323,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { undefined, "Password updated successfully", ).withResponse(null); - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/auth/reset-password") @@ -1207,9 +1340,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Invalid token", ); - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/auth/reset-password") @@ -1219,9 +1352,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return 500 when resetPassword throws an exception", async () => { - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app) .post("/auth/reset-password") @@ -1338,9 +1471,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { ), ); - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); mockUserAuthUseCase.signIn.mockResolvedValue(expectedResponse); const response = await supertest(testApp) @@ -1349,7 +1487,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .send({ email: "john@example.com", password: "Password123!" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(response.body.data.redirect).toBe("http://localhost:3000/dashboard"); + expect(response.body.data.redirect).toBe( + "http://localhost:3000/dashboard", + ); }); it("should not clear cookie and not return set-cookie for redirectTo if redirectTo cookie is absent (Line 63)", async () => { @@ -1369,10 +1509,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.OK); @@ -1381,7 +1521,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with invalid URL and error when getUrl throws (Lines 83, 84, 85)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const mockToken = "valid-token"; const mockUserPayload = { @@ -1399,10 +1539,10 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "john@example.com", }; - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(false); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(false); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); const response = await supertest(app) .get("/auth/session-info") @@ -1410,7 +1550,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(response.status).toBe(HttpStatusCodes.OK); expect(loggerSpy).toHaveBeenCalledWith( - expect.stringContaining("getSessionInfo Invalid URL: http://[invalid-url]"), + expect.stringContaining( + "getSessionInfo Invalid URL: http://[invalid-url]", + ), ); expect(loggerSpy.mock.calls[1][0]).toHaveProperty("message"); expect(loggerSpy.mock.calls[1][1]).toBe(true); @@ -1424,10 +1566,17 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { configurable: true, }); - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockResolvedValue(expectedResponse); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); + (UserAuthUseCase.prototype.signIn as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/sign-in") @@ -1446,14 +1595,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should return early when validationResponse has errorCode (Line 130)", async () => { - const validationResponse = new SecurityResponseModel("getSessionInfo").withError( - HttpStatusCodes.UNAUTHORIZED, - "Invalid Token", - ); - jest.mocked(getToken).mockReturnValue("bad-token"); - jest.mocked(validateToken).mockResolvedValue(validationResponse); + const validationResponse = new SecurityResponseModel( + "getSessionInfo", + ).withError(HttpStatusCodes.UNAUTHORIZED, "Invalid Token"); + vi.mocked(getToken).mockReturnValue("bad-token"); + vi.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockClear(); + vi.mocked(isSessionExpired).mockClear(); const response = await supertest(app).get("/auth/session-info"); @@ -1476,11 +1624,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { "getSessionInfo", ).withResponse(mockUserPayload); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); - const dateSpy = jest.spyOn(Date, "now").mockReturnValue(userIat * 1000 + maxAge + 1); + const dateSpy = vi + .spyOn(Date, "now") + .mockReturnValue(userIat * 1000 + maxAge + 1); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.UNAUTHORIZED); @@ -1507,18 +1657,21 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setPermissions([]) .build(); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue( + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( new ResponseModel("getSessionInfo").withResponse(mockDomainUser), ); - jest.mocked(createJwt).mockResolvedValue("new-jwt-token"); + vi.mocked(createJwt).mockResolvedValue("new-jwt-token"); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.OK); expect(UserQueryUseCase.prototype.sessionUser).toHaveBeenCalled(); - expect(createJwt).toHaveBeenCalledWith(expect.objectContaining({ roles: [] }), undefined); + expect(createJwt).toHaveBeenCalledWith( + expect.objectContaining({ roles: [] }), + undefined, + ); }); it("should return undefined authToken when mixed local/external aud and origin are provided (Line 218)", async () => { @@ -1548,16 +1701,20 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "admin@example.com", roles: ["admin"], }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("Admin User").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponseA); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue(refreshedResponse); - jest.mocked(createJwt).mockResolvedValue("new-refreshed-jwt-token"); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponseA); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( + refreshedResponse, + ); + vi.mocked(createJwt).mockResolvedValue("new-refreshed-jwt-token"); const responseA = await supertest(app).get("/auth/session-info"); expect(responseA.status).toBe(HttpStatusCodes.OK); @@ -1575,7 +1732,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { "getSessionInfo", ).withResponse(mockUserPayloadB); - jest.mocked(validateToken).mockResolvedValue(validationResponseB); + vi.mocked(validateToken).mockResolvedValue(validationResponseB); const responseB = await supertest(app) .get("/auth/session-info") @@ -1591,9 +1748,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with error and true flag when signIn throws (Line 290)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockRejectedValue( + (UserAuthUseCase.prototype.signIn as vi.Mock).mockRejectedValue( new Error("Unexpected sign-in error"), ); @@ -1607,10 +1764,17 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should verify transactionId is returned in signIn and signUp responses (Line 235 & 303)", async () => { - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedSignInResponse = new ResponseModel("signIn").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); - (UserAuthUseCase.prototype.signIn as jest.Mock).mockResolvedValue(expectedSignInResponse); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedSignInResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); + (UserAuthUseCase.prototype.signIn as vi.Mock).mockResolvedValue( + expectedSignInResponse, + ); const signInResponse = await supertest(app) .post("/auth/sign-in") @@ -1619,8 +1783,12 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(signInResponse.status).toBe(HttpStatusCodes.OK); expect(signInResponse.body.transactionId).toBe("signIn"); - const expectedSignUpResponse = new ResponseModel("signUp").withResponse(mockUser); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedSignUpResponse); + const expectedSignUpResponse = new ResponseModel("signUp").withResponse( + mockUser, + ); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedSignUpResponse, + ); const signUpResponse = await supertest(app).post("/auth/sign-up").send({ name: "John Doe", @@ -1638,7 +1806,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.SYSTEM_ERROR, "System failure", ); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockResolvedValue(expectedResponse); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/auth/sign-up").send({ name: "John Doe", @@ -1652,8 +1822,8 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with true flag when signUp throws (Line 344)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserAuthUseCase.prototype.signUp as jest.Mock).mockRejectedValue( + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + (UserAuthUseCase.prototype.signUp as vi.Mock).mockRejectedValue( new Error("Database offline"), ); @@ -1676,12 +1846,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { const authCookie = cookies.find((c) => c.includes("authToken=")); expect(authCookie).toBeDefined(); expect( - authCookie?.includes("Max-Age=0") || authCookie?.includes("Expires=Thu, 01 Jan 1970"), + authCookie?.includes("Max-Age=0") || + authCookie?.includes("Expires=Thu, 01 Jan 1970"), ).toBe(true); }); it("should call logger.err in validateGoogleCode when verification throws (Line 390)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const response = await supertest(app) .post("/auth/google/callback") @@ -1698,9 +1869,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setName("John Doe") .setEmail("john@example.com") .build(); - const expectedResponse = new ResponseModel("loginWithGoogle").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("google-jwt-token"); - (UserAuthUseCase.prototype.findOrCreate as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel( + "loginWithGoogle", + ).withResponse(mockUser); + vi.mocked(createJwt).mockResolvedValue("google-jwt-token"); + (UserAuthUseCase.prototype.findOrCreate as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/google/callback") @@ -1713,19 +1888,25 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should redirect to login with errorMessage when findOrCreate returns null data (Line 415)", async () => { - const expectedResponse = new ResponseModel("loginWithGoogle").withResponse(null); - (UserAuthUseCase.prototype.findOrCreate as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel( + "loginWithGoogle", + ).withResponse(null); + (UserAuthUseCase.prototype.findOrCreate as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/auth/google/callback") .send({ credential: "mock-google-id-token" }); expect(response.status).toBe(302); - expect(response.headers.location).toContain("errorMessage=Login%20failed"); + expect(response.headers.location).toContain( + "errorMessage=Login%20failed", + ); }); it("should call logger.err with true flag when google callback throws (Line 440)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const response = await supertest(app) .post("/auth/google/callback") @@ -1737,8 +1918,12 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should verify transactionId in myAccount call (Line 446)", async () => { - const expectedResponse = new ResponseModel("myAccount").withResponse(null); - (UserQueryUseCase.prototype.myAccount as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("myAccount").withResponse( + null, + ); + (UserQueryUseCase.prototype.myAccount as vi.Mock).mockResolvedValue( + expectedResponse, + ); await supertest(app).get("/auth/my-account"); expect(UserQueryUseCase.prototype.myAccount).toHaveBeenCalledWith( @@ -1747,8 +1932,8 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with true flag when my-account throws (Line 456)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserQueryUseCase.prototype.myAccount as jest.Mock).mockRejectedValue( + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + (UserQueryUseCase.prototype.myAccount as vi.Mock).mockRejectedValue( new Error("MyAccount failed"), ); @@ -1758,62 +1943,84 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should verify transactionId in updateProfile call (Line 470)", async () => { - const expectedResponse = new ResponseModel("updateMyAccountInformation").withResponse(null); - (UserManagementUseCase.prototype.updateProfile as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "updateMyAccountInformation", + ).withResponse(null); + ( + UserManagementUseCase.prototype.updateProfile as vi.Mock + ).mockResolvedValue(expectedResponse); - await supertest(app).put("/auth/my-account/information").send({ countryCode: "US" }); + await supertest(app) + .put("/auth/my-account/information") + .send({ countryCode: "US" }); - expect(UserManagementUseCase.prototype.updateProfile).toHaveBeenCalledWith( - expect.objectContaining({ transactionId: "updateMyAccountInformation" }), + expect( + UserManagementUseCase.prototype.updateProfile, + ).toHaveBeenCalledWith( + expect.objectContaining({ + transactionId: "updateMyAccountInformation", + }), ); }); it("should call logger.err with true flag when updateProfile throws (Line 490)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserManagementUseCase.prototype.updateProfile as jest.Mock).mockRejectedValue( - new Error("Update failed"), - ); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + ( + UserManagementUseCase.prototype.updateProfile as vi.Mock + ).mockRejectedValue(new Error("Update failed")); - await supertest(app).put("/auth/my-account/information").send({ countryCode: "US" }); + await supertest(app) + .put("/auth/my-account/information") + .send({ countryCode: "US" }); expect(loggerSpy).toHaveBeenCalledWith(expect.any(Error), true); loggerSpy.mockRestore(); }); it("should verify transactionId in updatePassword call (Line 502)", async () => { - const expectedResponse = new ResponseModel("passwordUpdate").withResponse(null); - (UserManagementUseCase.prototype.updatePassword as jest.Mock).mockResolvedValue( - expectedResponse, + const expectedResponse = new ResponseModel("passwordUpdate").withResponse( + null, ); + ( + UserManagementUseCase.prototype.updatePassword as vi.Mock + ).mockResolvedValue(expectedResponse); - await supertest(app) - .put("/auth/password-update") - .send({ currentPassword: "a", newPassword: "b", passwordConfirmation: "b" }); + await supertest(app).put("/auth/password-update").send({ + currentPassword: "a", + newPassword: "b", + passwordConfirmation: "b", + }); - expect(UserManagementUseCase.prototype.updatePassword).toHaveBeenCalledWith( + expect( + UserManagementUseCase.prototype.updatePassword, + ).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "passwordUpdate" }), ); }); it("should call logger.err with true flag when updatePassword throws (Line 523)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserManagementUseCase.prototype.updatePassword as jest.Mock).mockRejectedValue( - new Error("Pass failed"), - ); - - await supertest(app) - .put("/auth/password-update") - .send({ currentPassword: "a", newPassword: "b", passwordConfirmation: "b" }); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + ( + UserManagementUseCase.prototype.updatePassword as vi.Mock + ).mockRejectedValue(new Error("Pass failed")); + + await supertest(app).put("/auth/password-update").send({ + currentPassword: "a", + newPassword: "b", + passwordConfirmation: "b", + }); expect(loggerSpy).toHaveBeenCalledWith(expect.any(Error), true); loggerSpy.mockRestore(); }); it("should verify transactionId in getGuestData call (Line 534)", async () => { - const expectedResponse = new ResponseModel("signInAsGuest").withResponse(null); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("signInAsGuest").withResponse( + null, + ); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + expectedResponse, + ); await supertest(app).post("/auth/guest/sign-in").send({ guestId: "abc" }); @@ -1823,20 +2030,31 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should fallback to HOME_REDIRECT_URI during guest sign-in when redirect is empty (Line 572)", async () => { - const mockUser = User.builder().setId("guest-123").setName("Guest").build(); - const expectedResponse = new ResponseModel("signInAsGuest").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("guest-token"); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue(expectedResponse); + const mockUser = User.builder() + .setId("guest-123") + .setName("Guest") + .build(); + const expectedResponse = new ResponseModel("signInAsGuest").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("guest-token"); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/auth/guest/sign-in").send({ guestId: "abc" }); + const response = await supertest(app) + .post("/auth/guest/sign-in") + .send({ guestId: "abc" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(response.body.data.redirect).toBe(EnvVars.Auth.APP.HOME_REDIRECT_URI); + expect(response.body.data.redirect).toBe( + EnvVars.Auth.APP.HOME_REDIRECT_URI, + ); }); it("should call logger.err with true flag when guest sign-in throws (Line 577)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockRejectedValue( + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockRejectedValue( new Error("Guest throw"), ); @@ -1847,7 +2065,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should not execute catch block when url is not provided to /redirects (Line 593)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const response = await supertest(app).post("/auth/redirects").send({}); @@ -1857,14 +2075,16 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should execute catch block and log error when url is invalid in /redirects (Line 603)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const response = await supertest(app) .post("/auth/redirects") .send({ url: "not-a-valid-url" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(loggerSpy).toHaveBeenCalledWith("POST: /auth/redirects Invalid redirect URL:"); + expect(loggerSpy).toHaveBeenCalledWith( + "POST: /auth/redirects Invalid redirect URL:", + ); expect(loggerSpy.mock.calls[1][0]).toHaveProperty("message"); expect(loggerSpy.mock.calls[2][0]).toHaveProperty("message"); expect(loggerSpy.mock.calls[2][1]).toBe(true); @@ -1884,9 +2104,11 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(response.status).toBe(HttpStatusCodes.OK); const cookies = parseCookies(response); - expect(cookies.some((c) => c.includes("redirectTo=") && c.includes("SameSite=None"))).toBe( - true, - ); + expect( + cookies.some( + (c) => c.includes("redirectTo=") && c.includes("SameSite=None"), + ), + ).toBe(true); Object.defineProperty(EnvVars.CORS, "AllowedOriginsPatterns", { value: originalPatterns, @@ -1895,10 +2117,16 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should verify transactionId in forgotPassword call (Line 617)", async () => { - const expectedResponse = new ResponseModel("forgotPassword").withResponse(null); - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("forgotPassword").withResponse( + null, + ); + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockResolvedValue( + expectedResponse, + ); - await supertest(app).post("/auth/forgot-password").send({ email: "test@example.com" }); + await supertest(app) + .post("/auth/forgot-password") + .send({ email: "test@example.com" }); expect(UserPasswordUseCase.prototype.requestReset).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "forgotPassword" }), @@ -1910,28 +2138,38 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Email missing", ); - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/auth/forgot-password").send({ email: "" }); + const response = await supertest(app) + .post("/auth/forgot-password") + .send({ email: "" }); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should call logger.err with true flag when forgot-password throws (Line 633)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserPasswordUseCase.prototype.requestReset as jest.Mock).mockRejectedValue( + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + (UserPasswordUseCase.prototype.requestReset as vi.Mock).mockRejectedValue( new Error("Forgot error"), ); - await supertest(app).post("/auth/forgot-password").send({ email: "test@example.com" }); + await supertest(app) + .post("/auth/forgot-password") + .send({ email: "test@example.com" }); expect(loggerSpy).toHaveBeenCalledWith(expect.any(Error), true); loggerSpy.mockRestore(); }); it("should verify transactionId in verifyToken call (Line 646) and query token gets passed (Line 647)", async () => { - const expectedResponse = new ResponseModel("verifyToken").withResponse(null); - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("verifyToken").withResponse( + null, + ); + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockResolvedValue( + expectedResponse, + ); await supertest(app).get("/auth/verify-token").query({ token: "test" }); @@ -1948,16 +2186,20 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Expired", ); - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).get("/auth/verify-token").query({ token: "expired" }); + const response = await supertest(app) + .get("/auth/verify-token") + .query({ token: "expired" }); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should call logger.err with true flag when verifyToken throws (Line 662)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserPasswordUseCase.prototype.verifyToken as jest.Mock).mockRejectedValue( + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + (UserPasswordUseCase.prototype.verifyToken as vi.Mock).mockRejectedValue( new Error("Verify throw"), ); @@ -1968,12 +2210,16 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should verify transactionId in resetPassword call (Line 675)", async () => { - const expectedResponse = new ResponseModel("resetPassword").withResponse(null); - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockResolvedValue( - expectedResponse, + const expectedResponse = new ResponseModel("resetPassword").withResponse( + null, ); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockResolvedValue(expectedResponse); - await supertest(app).post("/auth/reset-password").send({ token: "t", password: "p" }); + await supertest(app) + .post("/auth/reset-password") + .send({ token: "t", password: "p" }); expect(UserPasswordUseCase.prototype.resetPassword).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "resetPassword" }), @@ -1985,9 +2231,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { DomainErrorCodes.INVALID_INPUT, "Fail", ); - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/auth/reset-password") @@ -1997,12 +2243,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with true flag when resetPassword throws (Line 692)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); - (UserPasswordUseCase.prototype.resetPassword as jest.Mock).mockRejectedValue( - new Error("Reset throw"), - ); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); + ( + UserPasswordUseCase.prototype.resetPassword as vi.Mock + ).mockRejectedValue(new Error("Reset throw")); - await supertest(app).post("/auth/reset-password").send({ token: "t", password: "p" }); + await supertest(app) + .post("/auth/reset-password") + .send({ token: "t", password: "p" }); expect(loggerSpy).toHaveBeenCalledWith(expect.any(Error), true); loggerSpy.mockRestore(); @@ -2039,9 +2287,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { ), ); - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); mockUserAuthUseCase.signIn.mockResolvedValue(expectedResponse); const response = await supertest(testApp) @@ -2050,7 +2303,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .send({ email: "john@example.com", password: "Password123!" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(response.body.data.redirect).toBe("http://my-home-domain.com/dashboard"); + expect(response.body.data.redirect).toBe( + "http://my-home-domain.com/dashboard", + ); Object.defineProperty(EnvVars.CORS, "AllowedOriginsPatterns", { value: originalPatterns, @@ -2059,7 +2314,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { }); it("should call logger.err with getSessionInfo when invalid redirect is passed during refresh (Line 208)", async () => { - const loggerSpy = jest.spyOn(logger, "err").mockImplementation(() => {}); + const loggerSpy = vi.spyOn(logger, "err").mockImplementation(() => {}); const mockToken = "valid-token"; const mockUserPayload = { @@ -2078,16 +2333,20 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { email: "admin@example.com", roles: ["admin"], }; - const refreshedResponse = new ResponseModel("getSessionInfo").withResponse( + const refreshedResponse = new ResponseModel( + "getSessionInfo", + ).withResponse( User.builder().setId("user-123").setName("Admin User").build(), ); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - jest.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); - (UserQueryUseCase.prototype.sessionUser as jest.Mock).mockResolvedValue(refreshedResponse); - jest.mocked(createJwt).mockResolvedValue("new-jwt-token"); + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + vi.mocked(sessionInfoToSessionUser).mockReturnValue(sessionUser); + (UserQueryUseCase.prototype.sessionUser as vi.Mock).mockResolvedValue( + refreshedResponse, + ); + vi.mocked(createJwt).mockResolvedValue("new-jwt-token"); const response = await supertest(app) .get("/auth/session-info") @@ -2095,13 +2354,15 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { expect(response.status).toBe(HttpStatusCodes.OK); expect(loggerSpy).toHaveBeenCalledWith( - expect.stringContaining("getSessionInfo Invalid URL: http://[invalid-url]"), + expect.stringContaining( + "getSessionInfo Invalid URL: http://[invalid-url]", + ), ); loggerSpy.mockRestore(); }); it("should verify permissions are passed correctly to hasPermissions middleware (Lines 445, 468, 501)", () => { - jest.mocked(hasPermissions).mockClear(); + vi.mocked(hasPermissions).mockClear(); createAuthRouter( mock(), @@ -2110,7 +2371,7 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { mock(), ); - const calls = jest.mocked(hasPermissions).mock.calls; + const calls = vi.mocked(hasPermissions).mock.calls; expect(calls).toHaveLength(3); expect(calls[0][0]).toEqual(["my-account::query"]); expect(calls[1][0]).toEqual(["my-account::update"]); @@ -2136,9 +2397,14 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { ), ); - const mockUser = User.builder().setId("user-123").setName("John Doe").build(); - const expectedResponse = new ResponseModel("signIn").withResponse(mockUser); - jest.mocked(createJwt).mockResolvedValue("jwt-token"); + const mockUser = User.builder() + .setId("user-123") + .setName("John Doe") + .build(); + const expectedResponse = new ResponseModel("signIn").withResponse( + mockUser, + ); + vi.mocked(createJwt).mockResolvedValue("jwt-token"); mockUserAuthUseCase.signIn.mockResolvedValue(expectedResponse); const originalPatterns = EnvVars.CORS.AllowedOriginsPatterns; @@ -2179,7 +2445,9 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { const redirectCookie = cookies.find((c) => c.includes("redirectTo=")); expect(redirectCookie).toBeDefined(); const decodedCookie = decodeURIComponent(redirectCookie ?? ""); - expect(decodedCookie.includes("redirectTo=data:text/html,hello")).toBe(true); + expect(decodedCookie.includes("redirectTo=data:text/html,hello")).toBe( + true, + ); Object.defineProperty(EnvVars.CORS, "AllowedOriginsPatterns", { value: originalPatterns, @@ -2205,13 +2473,13 @@ describe("AuthRouter Integration Tests - Fixed OAuth Mocks", () => { .setRoles(["guest", "other-role"]) .build(); - jest.mocked(getToken).mockReturnValue(mockToken); - jest.mocked(validateToken).mockResolvedValue(validationResponse); - jest.mocked(isSessionExpired).mockReturnValue(true); - (UserAuthUseCase.prototype.getGuestData as jest.Mock).mockResolvedValue( + vi.mocked(getToken).mockReturnValue(mockToken); + vi.mocked(validateToken).mockResolvedValue(validationResponse); + vi.mocked(isSessionExpired).mockReturnValue(true); + (UserAuthUseCase.prototype.getGuestData as vi.Mock).mockResolvedValue( new ResponseModel("getSessionInfo").withResponse(mockDomainUser), ); - jest.mocked(createJwt).mockResolvedValue("guest-jwt"); + vi.mocked(createJwt).mockResolvedValue("guest-jwt"); const response = await supertest(app).get("/auth/session-info"); expect(response.status).toBe(HttpStatusCodes.OK); diff --git a/src/EntryPoints/AuthRouter.ts b/src/EntryPoints/AuthRouter.ts index 20fde5b..228d549 100644 --- a/src/EntryPoints/AuthRouter.ts +++ b/src/EntryPoints/AuthRouter.ts @@ -1,33 +1,38 @@ -import EnvVars from "@src/common/EnvVars"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Nullable } from "@src/Domain/Core/Entity/Nullable"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Credentials } from "@src/Domain/User/Entity/Credentials"; -import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate"; -import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate"; -import { SessionInfoResponse } from "@src/Domain/User/Entity/SessionInfoResponse"; -import { SingInResponse } from "@src/Domain/User/Entity/SingInResponse"; -import { User } from "@src/Domain/User/Entity/User"; -import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration"; -import { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase"; -import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase"; -import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase"; +import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Credentials } from "@src/Domain/User/Entity/Credentials.js"; +import { PasswordUpdate } from "@src/Domain/User/Entity/PasswordUpdate.js"; +import { PersonalInformationUpdate } from "@src/Domain/User/Entity/PersonalInformationUpdate.js"; +import type { SessionInfoResponse } from "@src/Domain/User/Entity/SessionInfoResponse.js"; +import type { SingInResponse } from "@src/Domain/User/Entity/SingInResponse.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserRegistration } from "@src/Domain/User/Entity/UserRegistration.js"; +import type { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; +import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; +import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { + type SessionUser, createJwt, getToken, hasPermissions, isSessionExpired, sessionInfoToSessionUser, - SessionUser, validateToken, } from "@variamosple/variamos-security"; -import { CookieOptions, Request, Response, Router } from "express"; +import { + type CookieOptions, + type Request, + type Response, + Router, +} from "express"; import { OAuth2Client } from "google-auth-library"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const AUTH_ROUTE = "/auth"; @@ -39,24 +44,31 @@ export function createAuthRouter( ): Router { const authRouter = Router(); - const HOME_URL = new URL(EnvVars.Auth.APP.HOME_REDIRECT_URI || "http://localhost:3000"); + const HOME_URL = new URL( + EnvVars.Auth.APP.HOME_REDIRECT_URI || "http://localhost:3000", + ); const HOME_URL_HOST_REGEX = new RegExp(`^${HOME_URL.hostname}$`); - const isExternalDomain = (host?: string): boolean => !!host && !HOME_URL_HOST_REGEX.test(host); + const isExternalDomain = (host?: string): boolean => + !!host && !HOME_URL_HOST_REGEX.test(host); const isAllowedOrigin = (origin: string): boolean => { if ("null" === origin) { return true; } - return EnvVars.CORS.AllowedOriginsPatterns.findIndex((pattern) => pattern.test(origin)) !== -1; + return ( + EnvVars.CORS.AllowedOriginsPatterns.findIndex((pattern) => + pattern.test(origin), + ) !== -1 + ); }; const getRedirectUrl = ( transactionId: string, req: Request, res: Response, - remove: boolean = true, + remove = true, ): URL | undefined => { const redirectUrl = req.cookies.redirectTo as string | undefined; @@ -65,7 +77,10 @@ export function createAuthRouter( } if (remove) { - res.clearCookie("redirectTo", getCookieOptions({ sameSite: "none", maxAge: false })); + res.clearCookie( + "redirectTo", + getCookieOptions({ sameSite: "none", maxAge: false }), + ); } return getUrl(transactionId, redirectUrl); @@ -95,7 +110,9 @@ export function createAuthRouter( maxAge?: boolean; } - const getCookieOptions = (options: CookieOptionsInput = {}): CookieOptions => { + const getCookieOptions = ( + options: CookieOptionsInput = {}, + ): CookieOptions => { const domain = options.domain ?? EnvVars.CookieProps.Options.domain; const httpOnly = options.httpOnly ?? EnvVars.CookieProps.Options.httpOnly; const sameSite = options.sameSite ?? "strict"; @@ -128,8 +145,11 @@ export function createAuthRouter( const user = validationResponse.data; if (validationResponse.errorCode) { - return res.status(validationResponse.errorCode).json(validationResponse); - } else if (!isSessionExpired(user?.exp)) { + return res + .status(validationResponse.errorCode) + .json(validationResponse); + } + if (!isSessionExpired(user?.exp)) { const redirect = getRedirectUrl("getSessionInfo", req, res); setRedirectAuthToken(redirect, authToken); @@ -155,7 +175,8 @@ export function createAuthRouter( const currentDateInMs = Date.now(); // Get max refresh time - const refreshTimeInMs = user.iat * 1000 + EnvVars.CookieProps.Options.maxAge; + const refreshTimeInMs = + user.iat * 1000 + EnvVars.CookieProps.Options.maxAge; if (currentDateInMs > refreshTimeInMs) { return res @@ -168,16 +189,25 @@ export function createAuthRouter( ); } - const isGuest = user.roles?.some((role: string) => role.toLowerCase() === "guest") ?? false; + const isGuest = + user.roles?.some((role: string) => role.toLowerCase() === "guest") ?? + false; - const findSessionUserRequest = new RequestModel("getSessionInfo", user.sub); + const findSessionUserRequest = new RequestModel( + "getSessionInfo", + user.sub, + ); let refreshedUser: ResponseModel; if (isGuest) { - refreshedUser = await userAuthUseCase.getGuestData(findSessionUserRequest); + refreshedUser = await userAuthUseCase.getGuestData( + findSessionUserRequest, + ); } else { - refreshedUser = await userQueryUseCase.sessionUser(findSessionUserRequest); + refreshedUser = await userQueryUseCase.sessionUser( + findSessionUserRequest, + ); } if (!!refreshedUser.errorCode || !refreshedUser.data) { @@ -191,7 +221,14 @@ export function createAuthRouter( ); } - const { id, name, user: userName, email, roles, permissions } = refreshedUser.data; + const { + id, + name, + user: userName, + email, + roles, + permissions, + } = refreshedUser.data; const sessionUser: SessionUser = { id: id || "", @@ -214,7 +251,10 @@ export function createAuthRouter( user: sessionUser, authToken: isExternalDomain(user.aud) && - isExternalDomain(getUrl(response.transactionId || "", req.headers.origin)?.hostname) + isExternalDomain( + getUrl(response.transactionId || "", req.headers.origin) + ?.hostname, + ) ? token : undefined, redirect: redirect?.toString(), @@ -225,7 +265,12 @@ export function createAuthRouter( logger.err(error as Error); res .status(HttpStatusCodes.UNAUTHORIZED) - .json(response.withError(DomainErrorCodes.UNAUTHORIZED_ACCESS, "Session validation error")); + .json( + response.withError( + DomainErrorCodes.UNAUTHORIZED_ACCESS, + "Session validation error", + ), + ); } }); @@ -239,7 +284,10 @@ export function createAuthRouter( return res .status(HttpStatusCodes.BAD_REQUEST) .json( - response.withError(DomainErrorCodes.INVALID_INPUT, "Email and password are required."), + response.withError( + DomainErrorCodes.INVALID_INPUT, + "Email and password are required.", + ), ); } @@ -255,10 +303,18 @@ export function createAuthRouter( } if (!singInResponse.data) { - return res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(singInResponse); + return res + .status(HttpStatusCodes.INTERNAL_SERVER_ERROR) + .json(singInResponse); } - const { id, name, user: username, roles, permissions } = singInResponse.data; + const { + id, + name, + user: username, + roles, + permissions, + } = singInResponse.data; const sessionUser: SessionUser = { id: id || "", @@ -280,7 +336,9 @@ export function createAuthRouter( setRedirectAuthToken(redirect, token); response.data = { - redirect: redirect ? redirect.toString() : `${EnvVars.Auth.APP.HOME_REDIRECT_URI}`, + redirect: redirect + ? redirect.toString() + : `${EnvVars.Auth.APP.HOME_REDIRECT_URI}`, }; res.status(200).json(response); @@ -299,10 +357,8 @@ export function createAuthRouter( authRouter.post("/sign-up", async (req, res) => { const transactionId = "signUp"; - const { name, email, password, passwordConfirmation } = (req.body || {}) as Record< - string, - string - >; + const { name, email, password, passwordConfirmation } = (req.body || + {}) as Record; const successfulResponse = new ResponseModel( transactionId, undefined, @@ -311,7 +367,12 @@ export function createAuthRouter( let registration: UserRegistration; try { - registration = new UserRegistration(name, email, password, passwordConfirmation); + registration = new UserRegistration( + name, + email, + password, + passwordConfirmation, + ); } catch (error) { return res .status(HttpStatusCodes.BAD_REQUEST) @@ -324,7 +385,10 @@ export function createAuthRouter( } try { - const request = new RequestModel(transactionId, registration); + const request = new RequestModel( + transactionId, + registration, + ); const response = await userAuthUseCase.signUp(request); if (DomainErrorCodes.DUPLICATE_ENTITY === response.errorCode) { @@ -333,7 +397,9 @@ export function createAuthRouter( if (response.errorCode) { return res - .status(mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes)) + .status( + mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes), + ) .json(response); } @@ -360,7 +426,9 @@ export function createAuthRouter( res.status(200).json(new ResponseModel("logout")); }); - const validateGoogleCode = async (token: string): Promise => { + const validateGoogleCode = async ( + token: string, + ): Promise => { try { const client = new OAuth2Client(EnvVars.Auth.GOOGLE.CLIENT_ID); @@ -414,7 +482,14 @@ export function createAuthRouter( ); } - const { id, name, user: username, email, roles, permissions } = response.data; + const { + id, + name, + user: username, + email, + roles, + permissions, + } = response.data; const sessionUser: SessionUser = { id: id || "", @@ -436,30 +511,39 @@ export function createAuthRouter( res.redirect(302, `${EnvVars.Auth.APP.HOME_REDIRECT_URI}`); } catch (err) { logger.err(err as Error, true); - res.redirect(302, `${EnvVars.Auth.APP.LOGIN_REDIRECT_URI}?errorMessage=Login error.`); + res.redirect( + 302, + `${EnvVars.Auth.APP.LOGIN_REDIRECT_URI}?errorMessage=Login error.`, + ); } }); - authRouter.get("/my-account", hasPermissions(["my-account::query"]), async (req, res) => { - const transactionId = "myAccount"; - const user = req.user as SessionUser; - try { - const request = new RequestModel(transactionId, user.id); + authRouter.get( + "/my-account", + hasPermissions(["my-account::query"]), + async (req, res) => { + const transactionId = "myAccount"; + const user = req.user as SessionUser; + try { + const request = new RequestModel(transactionId, user.id); - const response = await userQueryUseCase.myAccount(request); + const response = await userQueryUseCase.myAccount(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); - res.status(status).json(response); - } catch (error) { - logger.err(error as Error, true); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(500).json(response); - } - }); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); + res.status(status).json(response); + } catch (error) { + logger.err(error as Error, true); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(500).json(response); + } + }, + ); authRouter.put( "/my-account/information", @@ -467,7 +551,9 @@ export function createAuthRouter( async (req, res) => { const transactionId = "updateMyAccountInformation"; const user = req.user as SessionUser; - const personalInformation = (req.body || {}) as { countryCode?: string | null }; + const personalInformation = (req.body || {}) as { + countryCode?: string | null; + }; try { const personalInformationUpdate = PersonalInformationUpdate.builder() @@ -482,7 +568,9 @@ export function createAuthRouter( const response = await userManagementUseCase.updateProfile(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error, true); @@ -496,37 +584,41 @@ export function createAuthRouter( }, ); - authRouter.put("/password-update", hasPermissions(["my-account::update"]), async (req, res) => { - const transactionId = "passwordUpdate"; - const user = req.user as SessionUser; - const { currentPassword, newPassword, passwordConfirmation } = (req.body || {}) as Record< - string, - string - >; - try { - const passwordUpdate = PasswordUpdate.builder() - .setId(user.id) - .setCurrentPassword(currentPassword) - .setNewPassword(newPassword) - .setPasswordConfirmation(passwordConfirmation) - .build(); + authRouter.put( + "/password-update", + hasPermissions(["my-account::update"]), + async (req, res) => { + const transactionId = "passwordUpdate"; + const user = req.user as SessionUser; + const { currentPassword, newPassword, passwordConfirmation } = + (req.body || {}) as Record; + try { + const passwordUpdate = PasswordUpdate.builder() + .setId(user.id) + .setCurrentPassword(currentPassword) + .setNewPassword(newPassword) + .setPasswordConfirmation(passwordConfirmation) + .build(); - const response = await userManagementUseCase.updatePassword( - new RequestModel(transactionId, passwordUpdate), - ); + const response = await userManagementUseCase.updatePassword( + new RequestModel(transactionId, passwordUpdate), + ); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); - res.status(status).json(response); - } catch (error) { - logger.err(error as Error, true); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(500).json(response); - } - }); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); + res.status(status).json(response); + } catch (error) { + logger.err(error as Error, true); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(500).json(response); + } + }, + ); authRouter.post("/guest/sign-in", async (req, res) => { const transactionId = "signInAsGuest"; @@ -538,11 +630,15 @@ export function createAuthRouter( const guestResponse = await userAuthUseCase.getGuestData(request); if (guestResponse.errorCode) { - return res.status(mapDomainErrorToHttpStatus(guestResponse.errorCode)).json(guestResponse); + return res + .status(mapDomainErrorToHttpStatus(guestResponse.errorCode)) + .json(guestResponse); } if (!guestResponse.data) { - return res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(guestResponse); + return res + .status(HttpStatusCodes.INTERNAL_SERVER_ERROR) + .json(guestResponse); } const { id, name, user, email, roles, permissions } = guestResponse.data; @@ -567,7 +663,9 @@ export function createAuthRouter( response.data = { id: id || "", - redirect: redirect ? redirect.toString() : `${EnvVars.Auth.APP.HOME_REDIRECT_URI}`, + redirect: redirect + ? redirect.toString() + : `${EnvVars.Auth.APP.HOME_REDIRECT_URI}`, }; res.status(200).json(response); @@ -671,7 +769,10 @@ export function createAuthRouter( authRouter.post("/reset-password", async (req, res) => { const transactionId = "resetPassword"; - const { token = "", password = "" } = (req.body || {}) as Record; + const { token = "", password = "" } = (req.body || {}) as Record< + string, + string + >; try { const resetResponse = await userPasswordUseCase.resetPassword( @@ -682,7 +783,9 @@ export function createAuthRouter( ); if (resetResponse.errorCode) { - return res.status(mapDomainErrorToHttpStatus(resetResponse.errorCode)).json(resetResponse); + return res + .status(mapDomainErrorToHttpStatus(resetResponse.errorCode)) + .json(resetResponse); } res.status(200).json(resetResponse); diff --git a/src/EntryPoints/BugRouter.spec.ts b/src/EntryPoints/BugRouter.spec.ts index 0a386dc..1dbf18a 100644 --- a/src/EntryPoints/BugRouter.spec.ts +++ b/src/EntryPoints/BugRouter.spec.ts @@ -1,8 +1,12 @@ -import { mock } from "jest-mock-extended"; -const mockValidateSession = jest.fn(); - -jest.mock("@variamosple/variamos-security", () => ({ - isAuthenticated: (req: express.Request, _res: express.Response, next: express.NextFunction) => { +import { mock } from "vitest-mock-extended"; +const mockValidateSession = vi.fn(); + +vi.mock("@variamosple/variamos-security", () => ({ + isAuthenticated: ( + req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { (req as { user?: { id: string; email?: string } }).user = { id: "admin-123", email: "admin@example.com", @@ -10,35 +14,52 @@ jest.mock("@variamosple/variamos-security", () => ({ next(); }, hasPermissions: - () => (req: express.Request, _res: express.Response, next: express.NextFunction) => + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => + next(), + isLogged: + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => + next(), + checkSession: + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => next(), - isLogged: () => (req: express.Request, _res: express.Response, next: express.NextFunction) => - next(), - checkSession: () => (req: express.Request, _res: express.Response, next: express.NextFunction) => - next(), validateSession: (token: string) => mockValidateSession(token), })); -import request from "supertest"; -import express, { RequestHandler } from "express"; +import { Bug } from "@src/Domain/Bug/Entity/Bug.js"; +import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment.js"; +import { BugNote } from "@src/Domain/Bug/Entity/BugNote.js"; +import type { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog.js"; +import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; +import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; +import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js"; +import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; +import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import cookieParser from "cookie-parser"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Bug } from "@src/Domain/Bug/Entity/Bug"; -import { BugNote } from "@src/Domain/Bug/Entity/BugNote"; -import { BugStatusLog } from "@src/Domain/Bug/Entity/BugStatusLog"; -import { BugAttachment } from "@src/Domain/Bug/Entity/BugAttachment"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { createBugRouter } from "./BugRouter"; -import { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase"; -import { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase"; -import { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase"; -import { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase"; -import { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase"; -import multer from "multer"; +import express, { type RequestHandler } from "express"; import logger from "jet-logger"; +import multer from "multer"; +import request from "supertest"; +import { createBugRouter } from "./BugRouter.js"; -const mockLoggerInfo = jest.spyOn(logger, "info").mockImplementation(); -const mockLoggerErr = jest.spyOn(logger, "err").mockImplementation(); +const mockLoggerInfo = vi.spyOn(logger, "info").mockImplementation(); +const mockLoggerErr = vi.spyOn(logger, "err").mockImplementation(); const mockBugSubmissionUseCase = mock(); const mockBugLifecycleUseCase = mock(); @@ -48,7 +69,7 @@ const mockBugAttachmentUseCase = mock(); // Use memory storage for testing to bypass physical disk writes and keep tests clean const mockUpload = multer({ storage: multer.memoryStorage() }); -const mockAuth: RequestHandler = (req, res, next) => { +const mockAuth: RequestHandler = (req, _res, next) => { (req as { user?: { id: string; email?: string } }).user = { id: "admin-123", email: "admin@example.com", @@ -80,13 +101,17 @@ app.use( describe("BugRouter HTTP Integration Tests", () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /", () => { it("should return 200 and bug list on success", async () => { const mockBugs = [ - Bug.builder().setId("gh-1").setTitle("GitHub Issue 1").setStatus("open").build(), + Bug.builder() + .setId("gh-1") + .setTitle("GitHub Issue 1") + .setStatus("open") + .build(), ]; mockBugQueryUseCase.queryBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse(mockBugs), @@ -114,7 +139,9 @@ describe("BugRouter HTTP Integration Tests", () => { ), ); - const res = await request(app).get("/bugs").query({ repo: "invalid-repo" }); + const res = await request(app) + .get("/bugs") + .query({ repo: "invalid-repo" }); expect(res.status).toBe(400); expect(res.body.message).toBe("Invalid repository format"); @@ -124,13 +151,19 @@ describe("BugRouter HTTP Integration Tests", () => { describe("GET /bugs/local", () => { it("should fetch local inbox bugs successfully", async () => { const localBugs = [ - Bug.builder().setId("local-1").setTitle("Local Bug 1").setStatus("pending").build(), + Bug.builder() + .setId("local-1") + .setTitle("Local Bug 1") + .setStatus("pending") + .build(), ]; mockBugQueryUseCase.queryLocalBugs.mockResolvedValue( new ResponseModel("tx-id").withResponse(localBugs), ); - const res = await request(app).get("/bugs/local").query({ status: "pending" }); + const res = await request(app) + .get("/bugs/local") + .query({ status: "pending" }); expect(res.status).toBe(200); expect(res.body.data[0].id).toBe("local-1"); @@ -144,7 +177,10 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs/:id/reject", () => { it("should successfully reject a local bug", async () => { - const rejectedBug = Bug.builder().setId("local-1").setStatus("rejected").build(); + const rejectedBug = Bug.builder() + .setId("local-1") + .setStatus("rejected") + .build(); mockBugLifecycleUseCase.rejectBug.mockResolvedValue( new ResponseModel("tx-id").withResponse(rejectedBug), ); @@ -178,7 +214,10 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs/:id/restore", () => { it("should successfully restore a bug", async () => { - const restoredBug = Bug.builder().setId("local-1").setStatus("pending").build(); + const restoredBug = Bug.builder() + .setId("local-1") + .setStatus("pending") + .build(); mockBugLifecycleUseCase.restoreBug.mockResolvedValue( new ResponseModel("tx-id").withResponse(restoredBug), ); @@ -199,7 +238,9 @@ describe("BugRouter HTTP Integration Tests", () => { describe("GET /bugs/repos", () => { it("should successfully query managed repos", async () => { mockBugQueryUseCase.queryBugRepos.mockResolvedValue( - new ResponseModel("tx-id").withResponse(["VariaMos/VariaMosAdmin"]), + new ResponseModel("tx-id").withResponse([ + "VariaMos/VariaMosAdmin", + ]), ); const res = await request(app).get("/bugs/repos"); @@ -214,7 +255,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when queryBugRepos throws an exception", async () => { - mockBugQueryUseCase.queryBugRepos.mockRejectedValue(new Error("Internal Config Fail")); + mockBugQueryUseCase.queryBugRepos.mockRejectedValue( + new Error("Internal Config Fail"), + ); const res = await request(app).get("/bugs/repos"); @@ -241,7 +284,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when queryCategories throws an exception", async () => { - mockBugQueryUseCase.queryCategories.mockRejectedValue(new Error("Database Query Failed")); + mockBugQueryUseCase.queryCategories.mockRejectedValue( + new Error("Database Query Failed"), + ); const res = await request(app).get("/bugs/categories"); @@ -252,7 +297,10 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs", () => { it("should successfully create a new local bug without attachment", async () => { - const newBug = Bug.builder().setId("local-new").setTitle("UI Crash").build(); + const newBug = Bug.builder() + .setId("local-new") + .setTitle("UI Crash") + .build(); mockBugSubmissionUseCase.createBug.mockResolvedValue( new ResponseModel("tx-id").withResponse(newBug), ); @@ -307,7 +355,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when creation throws an error", async () => { - mockBugSubmissionUseCase.createBug.mockRejectedValue(new Error("Required fields missing")); + mockBugSubmissionUseCase.createBug.mockRejectedValue( + new Error("Required fields missing"), + ); const res = await request(app).post("/bugs").send({}); @@ -334,7 +384,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when fetching history throws", async () => { - mockBugQueryUseCase.queryHistory.mockRejectedValue(new Error("DB Query Timeout")); + mockBugQueryUseCase.queryHistory.mockRejectedValue( + new Error("DB Query Timeout"), + ); const res = await request(app).get("/bugs/local-1/history"); @@ -345,7 +397,10 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs/:id/status", () => { it("should successfully update bug status", async () => { - const updatedBug = Bug.builder().setId("local-1").setStatus("closed").build(); + const updatedBug = Bug.builder() + .setId("local-1") + .setStatus("closed") + .build(); mockBugLifecycleUseCase.updateStatus.mockResolvedValue( new ResponseModel("tx-id").withResponse(updatedBug), ); @@ -381,9 +436,13 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when update status throws", async () => { - mockBugLifecycleUseCase.updateStatus.mockRejectedValue(new Error("Update failed")); + mockBugLifecycleUseCase.updateStatus.mockRejectedValue( + new Error("Update failed"), + ); - const res = await request(app).post("/bugs/local-1/status").send({ status: "closed" }); + const res = await request(app) + .post("/bugs/local-1/status") + .send({ status: "closed" }); expect(res.status).toBe(400); expect(res.body.error).toBe("Update failed"); @@ -392,7 +451,9 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs/:id/reject exception routing", () => { it("should return 400 when rejectBug throws exception", async () => { - mockBugLifecycleUseCase.rejectBug.mockRejectedValue(new Error("Reject exception")); + mockBugLifecycleUseCase.rejectBug.mockRejectedValue( + new Error("Reject exception"), + ); const res = await request(app).post("/bugs/local-1/reject").send(); @@ -403,7 +464,9 @@ describe("BugRouter HTTP Integration Tests", () => { describe("POST /bugs/:id/restore exception routing", () => { it("should return 400 when restoreBug throws exception", async () => { - mockBugLifecycleUseCase.restoreBug.mockRejectedValue(new Error("Restore exception")); + mockBugLifecycleUseCase.restoreBug.mockRejectedValue( + new Error("Restore exception"), + ); const res = await request(app).post("/bugs/local-1/restore").send(); @@ -414,7 +477,9 @@ describe("BugRouter HTTP Integration Tests", () => { describe("GET /bugs error routing", () => { it("should return 400 when queryBugs throws an exception", async () => { - mockBugQueryUseCase.queryBugs.mockRejectedValue(new Error("Query exception")); + mockBugQueryUseCase.queryBugs.mockRejectedValue( + new Error("Query exception"), + ); const res = await request(app).get("/bugs"); @@ -425,7 +490,9 @@ describe("BugRouter HTTP Integration Tests", () => { describe("GET /bugs/local error routing", () => { it("should return 400 when queryLocalBugs throws an exception", async () => { - mockBugQueryUseCase.queryLocalBugs.mockRejectedValue(new Error("Query local exception")); + mockBugQueryUseCase.queryLocalBugs.mockRejectedValue( + new Error("Query local exception"), + ); const res = await request(app).get("/bugs/local"); @@ -467,7 +534,10 @@ describe("BugRouter HTTP Integration Tests", () => { it("should return the exact numeric code if it is an unknown number", async () => { mockBugQueryUseCase.queryBugs.mockResolvedValue( - new ResponseModel("tx-id").withError("418" as unknown as DomainErrorCodes, "Teapot"), + new ResponseModel("tx-id").withError( + "418" as unknown as DomainErrorCodes, + "Teapot", + ), ); const res = await request(app).get("/bugs"); expect(res.status).toBe(418); @@ -494,7 +564,9 @@ describe("BugRouter HTTP Integration Tests", () => { const res = await request(app).post("/bugs/sync").send(); expect(res.status).toBe(200); - expect(res.body.message).toContain("synchronization completed successfully"); + expect(res.body.message).toContain( + "synchronization completed successfully", + ); expect(mockBugSyncUseCase.syncBugs).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "syncBugs", @@ -517,7 +589,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should return 400 when syncBugs throws an exception", async () => { - mockBugSyncUseCase.syncBugs.mockRejectedValue(new Error("Sync exception")); + mockBugSyncUseCase.syncBugs.mockRejectedValue( + new Error("Sync exception"), + ); const res = await request(app).post("/bugs/sync").send(); @@ -533,7 +607,7 @@ describe("BugRouter HTTP Integration Tests", () => { guestApp = express(); guestApp.use(cookieParser()); guestApp.use(express.json()); - const noAuth: RequestHandler = (req, res, next) => next(); + const noAuth: RequestHandler = (_req, _res, next) => next(); guestApp.use( "/bugs", createBugRouter( @@ -563,7 +637,9 @@ describe("BugRouter HTTP Integration Tests", () => { expect(res.status).toBe(201); expect(mockValidateSession).not.toHaveBeenCalled(); - expect(mockLoggerInfo).toHaveBeenCalledWith("POST /bugs: Extracted token: none"); + expect(mockLoggerInfo).toHaveBeenCalledWith( + "POST /bugs: Extracted token: none", + ); expect(mockBugSubmissionUseCase.createBug).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "createBug", @@ -647,7 +723,9 @@ describe("BugRouter HTTP Integration Tests", () => { mockBugSubmissionUseCase.createBug.mockResolvedValue( new ResponseModel("tx-id").withResponse(newBug), ); - mockValidateSession.mockRejectedValue(new Error("Session validation error")); + mockValidateSession.mockRejectedValue( + new Error("Session validation error"), + ); const res = await request(guestApp) .post("/bugs") @@ -797,7 +875,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should handle unexpected errors during attachment upload and return 400", async () => { - mockBugAttachmentUseCase.addAttachment.mockRejectedValue(new Error("Upload failed")); + mockBugAttachmentUseCase.addAttachment.mockRejectedValue( + new Error("Upload failed"), + ); const res = await request(app) .post("/bugs/local-1/attachments") @@ -833,7 +913,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should handle unexpected errors during attachment deletion and return 400", async () => { - mockBugAttachmentUseCase.deleteAttachment.mockRejectedValue(new Error("Delete failed")); + mockBugAttachmentUseCase.deleteAttachment.mockRejectedValue( + new Error("Delete failed"), + ); const res = await request(app).delete("/bugs/attachments/1"); @@ -857,7 +939,9 @@ describe("BugRouter HTTP Integration Tests", () => { ), ); - const res = await request(app).post("/bugs/local-1/notes").send({ body: "Hello note" }); + const res = await request(app) + .post("/bugs/local-1/notes") + .send({ body: "Hello note" }); expect(res.status).toBe(200); expect(res.body.data.id).toBe(10); @@ -874,9 +958,13 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should handle unexpected errors during note creation and return 400", async () => { - mockBugAttachmentUseCase.createNote.mockRejectedValue(new Error("Note creation failed")); + mockBugAttachmentUseCase.createNote.mockRejectedValue( + new Error("Note creation failed"), + ); - const res = await request(app).post("/bugs/local-1/notes").send({ body: "Hello note" }); + const res = await request(app) + .post("/bugs/local-1/notes") + .send({ body: "Hello note" }); expect(res.status).toBe(400); expect(res.body.error).toBe("Note creation failed"); @@ -905,7 +993,9 @@ describe("BugRouter HTTP Integration Tests", () => { }); it("should handle unexpected errors during notes query and return 400", async () => { - mockBugQueryUseCase.queryNotes.mockRejectedValue(new Error("Notes query failed")); + mockBugQueryUseCase.queryNotes.mockRejectedValue( + new Error("Notes query failed"), + ); const res = await request(app).get("/bugs/local-1/notes"); expect(res.status).toBe(400); diff --git a/src/EntryPoints/BugRouter.ts b/src/EntryPoints/BugRouter.ts index c990593..4ebd2bb 100644 --- a/src/EntryPoints/BugRouter.ts +++ b/src/EntryPoints/BugRouter.ts @@ -1,15 +1,23 @@ -import { Router, Request, Response, RequestHandler } from "express"; -import { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase"; -import { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase"; -import { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase"; -import { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase"; -import { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase"; -import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter.js"; +import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; +import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; +import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js"; +import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; +import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { + type SessionUser, + validateSession, +} from "@variamosple/variamos-security"; +import { + type Request, + type RequestHandler, + type Response, + Router, +} from "express"; import logger from "jet-logger"; -import { validateSession, SessionUser } from "@variamosple/variamos-security"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; /** * Factory function to create Bug Router with decoupled dependency injection @@ -51,7 +59,9 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }); @@ -73,12 +83,14 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }); // Get managed repositories - router.get("/repos", authMiddleware, async (req: Request, res: Response) => { + router.get("/repos", authMiddleware, async (_req: Request, res: Response) => { const transactionId = "queryBugRepos"; try { const request = new RequestModel(transactionId); @@ -88,12 +100,14 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }); // Get allowed categories - router.get("/categories", async (req: Request, res: Response) => { + router.get("/categories", async (_req: Request, res: Response) => { const transactionId = "queryCategories"; try { const request = new RequestModel(transactionId); @@ -103,79 +117,103 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }); // Create a new bug - router.post("/", upload.single("file"), async (req: Request, res: Response) => { - const transactionId = "createBug"; - const { title, description, priority, category, githubRepo, reporterEmail } = req.body as { - title?: string; - description?: string; - priority?: string; - category?: string; - githubRepo?: string; - reporterEmail?: string; - }; - let adminId: string | undefined = undefined; - if ((req as RequestWithUser).user) { - adminId = (req as RequestWithUser).user.id; - } else { - const token = - (req.cookies?.authToken as string | undefined) || req.headers.authorization?.split(" ")[1]; - logger.info( - "POST /bugs: Extracted token: " + (token ? token.substring(0, 15) + "..." : "none"), - ); - if (token) { - try { - const session = await validateSession(token); - logger.info("POST /bugs: Session validation result: " + JSON.stringify(session)); - if (session && session.data) { - const sessionData = session.data as { id?: string; sub?: string }; - const resolvedId = sessionData.id || sessionData.sub; - if (resolvedId) { - adminId = resolvedId; + router.post( + "/", + upload.single("file"), + async (req: Request, res: Response) => { + const transactionId = "createBug"; + const { + title, + description, + priority, + category, + githubRepo, + reporterEmail, + } = req.body as { + title?: string; + description?: string; + priority?: string; + category?: string; + githubRepo?: string; + reporterEmail?: string; + }; + let adminId: string | undefined = undefined; + if ((req as RequestWithUser).user) { + adminId = (req as RequestWithUser).user.id; + } else { + const token = + (req.cookies?.authToken as string | undefined) || + req.headers.authorization?.split(" ")[1]; + logger.info( + `POST /bugs: Extracted token: ${token ? `${token.substring(0, 15)}...` : "none"}`, + ); + if (token) { + try { + const session = await validateSession(token); + logger.info( + `POST /bugs: Session validation result: ${JSON.stringify(session)}`, + ); + if (session?.data) { + const sessionData = session.data as { id?: string; sub?: string }; + const resolvedId = sessionData.id || sessionData.sub; + if (resolvedId) { + adminId = resolvedId; + } } + } catch (e) { + logger.err("POST /bugs: Error during session validation:"); + logger.err(e as Error); } - } catch (e) { - logger.err("POST /bugs: Error during session validation:"); - logger.err(e as Error); } } - } - try { - const validPriorities = ["low", "medium", "high"]; - const resolvedPriority = validPriorities.includes(priority || "") - ? (priority as "low" | "medium" | "high") - : "medium"; - - const payload = { - title: title || "", - description: description || "", - priority: resolvedPriority, - category: category || "", - githubRepo: githubRepo || undefined, - createdById: adminId, - reporterEmail: reporterEmail || undefined, - file: req.file - ? { - filename: req.file.filename, - mimetype: req.file.mimetype, - } - : null, - }; - const request = new RequestModel(transactionId, payload); - const response = await bugSubmissionUseCase.createBug(request); + try { + const validPriorities = ["low", "medium", "high"]; + const resolvedPriority = validPriorities.includes(priority || "") + ? (priority as "low" | "medium" | "high") + : "medium"; - const code = mapDomainErrorToHttpStatus(response.errorCode, HttpStatusCodes.CREATED); - res.status(code).json(response); - } catch (error) { - logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); - } - }); + const payload = { + title: title || "", + description: description || "", + priority: resolvedPriority, + category: category || "", + githubRepo: githubRepo || undefined, + createdById: adminId, + reporterEmail: reporterEmail || undefined, + file: req.file + ? { + filename: req.file.filename, + mimetype: req.file.mimetype, + } + : null, + }; + const request = new RequestModel( + transactionId, + payload, + ); + const response = await bugSubmissionUseCase.createBug(request); + + const code = mapDomainErrorToHttpStatus( + response.errorCode, + HttpStatusCodes.CREATED, + ); + res.status(code).json(response); + } catch (error) { + logger.err(error); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); + } + }, + ); // Get status log history router.get( @@ -193,7 +231,9 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); @@ -205,7 +245,15 @@ export function createBugRouter( async (req: Request<{ id: string }>, res: Response) => { const transactionId = "updateStatus"; const { id } = req.params; - const { status, comment, title, description, priority, category, githubRepo } = req.body as { + const { + status, + comment, + title, + description, + priority, + category, + githubRepo, + } = req.body as { status?: string; comment?: string; title?: string; @@ -235,14 +283,19 @@ export function createBugRouter( category: category || undefined, githubRepo: githubRepo || undefined, }; - const request = new RequestModel(transactionId, payload); + const request = new RequestModel( + transactionId, + payload, + ); const response = await bugLifecycleUseCase.updateStatus(request); const code = mapDomainErrorToHttpStatus(response.errorCode); res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); @@ -258,14 +311,19 @@ export function createBugRouter( try { const payload = { id, adminId }; - const request = new RequestModel(transactionId, payload); + const request = new RequestModel( + transactionId, + payload, + ); const response = await bugLifecycleUseCase.restoreBug(request); const code = mapDomainErrorToHttpStatus(response.errorCode); res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); @@ -281,20 +339,25 @@ export function createBugRouter( try { const payload = { id, adminId }; - const request = new RequestModel(transactionId, payload); + const request = new RequestModel( + transactionId, + payload, + ); const response = await bugLifecycleUseCase.rejectBug(request); const code = mapDomainErrorToHttpStatus(response.errorCode); res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); // Synchronize with GitHub - router.post("/sync", authMiddleware, async (req: Request, res: Response) => { + router.post("/sync", authMiddleware, async (_req: Request, res: Response) => { const transactionId = "syncBugs"; try { const request = new RequestModel(transactionId); @@ -310,7 +373,9 @@ export function createBugRouter( } } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }); @@ -323,7 +388,9 @@ export function createBugRouter( const transactionId = "addAttachment"; const { id } = req.params; if (!req.file) { - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: "File attachment is required." }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: "File attachment is required." }); return; } try { @@ -334,13 +401,21 @@ export function createBugRouter( mimetype: req.file.mimetype, }, }; - const request = new RequestModel(transactionId, payload); + const request = new RequestModel( + transactionId, + payload, + ); const response = await bugAttachmentUseCase.addAttachment(request); - const code = mapDomainErrorToHttpStatus(response.errorCode, HttpStatusCodes.CREATED); + const code = mapDomainErrorToHttpStatus( + response.errorCode, + HttpStatusCodes.CREATED, + ); res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); @@ -359,45 +434,59 @@ export function createBugRouter( res.status(code).json(response); } catch (error) { logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); } }, ); // Create bug note - router.post("/:id/notes", authMiddleware, async (req: Request<{ id: string }>, res: Response) => { - const transactionId = "createBugNote"; - const { id } = req.params; - const { body } = req.body as { body?: string }; - const authorId = (req as RequestWithUser).user.id; + router.post( + "/:id/notes", + authMiddleware, + async (req: Request<{ id: string }>, res: Response) => { + const transactionId = "createBugNote"; + const { id } = req.params; + const { body } = req.body as { body?: string }; + const authorId = (req as RequestWithUser).user.id; - try { - const payload = { bugId: id, body: body || "", authorId }; - const request = new RequestModel(transactionId, payload); - const response = await bugAttachmentUseCase.createNote(request); - const code = mapDomainErrorToHttpStatus(response.errorCode); - res.status(code).json(response); - } catch (error) { - logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); - } - }); + try { + const payload = { bugId: id, body: body || "", authorId }; + const request = new RequestModel(transactionId, payload); + const response = await bugAttachmentUseCase.createNote(request); + const code = mapDomainErrorToHttpStatus(response.errorCode); + res.status(code).json(response); + } catch (error) { + logger.err(error); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); + } + }, + ); // Query bug notes - router.get("/:id/notes", authMiddleware, async (req: Request<{ id: string }>, res: Response) => { - const transactionId = "queryBugNotes"; - const { id } = req.params; + router.get( + "/:id/notes", + authMiddleware, + async (req: Request<{ id: string }>, res: Response) => { + const transactionId = "queryBugNotes"; + const { id } = req.params; - try { - const request = new RequestModel(transactionId, id); - const response = await bugQueryUseCase.queryNotes(request); - const code = mapDomainErrorToHttpStatus(response.errorCode); - res.status(code).json(response); - } catch (error) { - logger.err(error); - res.status(HttpStatusCodes.BAD_REQUEST).json({ error: (error as Error).message }); - } - }); + try { + const request = new RequestModel(transactionId, id); + const response = await bugQueryUseCase.queryNotes(request); + const code = mapDomainErrorToHttpStatus(response.errorCode); + res.status(code).json(response); + } catch (error) { + logger.err(error); + res + .status(HttpStatusCodes.BAD_REQUEST) + .json({ error: (error as Error).message }); + } + }, + ); return router; } diff --git a/src/EntryPoints/ConfigurationRouter.test.ts b/src/EntryPoints/ConfigurationRouter.test.ts index 430c683..61a4388 100644 --- a/src/EntryPoints/ConfigurationRouter.test.ts +++ b/src/EntryPoints/ConfigurationRouter.test.ts @@ -1,8 +1,8 @@ +import type { Menu } from "@src/Domain/Menu/Entity/Menu.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createConfigurationRouter } from "./ConfigurationRouter"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Menu } from "@src/Domain/Menu/Entity/Menu"; +import { createConfigurationRouter } from "./ConfigurationRouter.js"; interface MenuApiResponse { data: Menu; diff --git a/src/EntryPoints/ConfigurationRouter.ts b/src/EntryPoints/ConfigurationRouter.ts index b0f221f..6f1fa17 100644 --- a/src/EntryPoints/ConfigurationRouter.ts +++ b/src/EntryPoints/ConfigurationRouter.ts @@ -1,6 +1,6 @@ -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Menu } from "@src/Domain/Menu/Entity/Menu"; -import { Request, Router } from "express"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { Menu } from "@src/Domain/Menu/Entity/Menu.js"; +import { type Request, Router } from "express"; export const CONFIGURATION_V1_ROUTE = "/v1/configurations"; @@ -96,42 +96,42 @@ const MENU: Menu = { }, { title: "Report a problem", - location: `https://github.com/variamosple/VariaMosLanguages/issues/new`, + location: "https://github.com/variamosple/VariaMosLanguages/issues/new", accessibleFrom: "/variamos_languages/", target: "newWindow", allowedPermissions: [], }, { title: "Issues", - location: `https://github.com/variamosple/VariaMosLanguages/issues/`, + location: "https://github.com/variamosple/VariaMosLanguages/issues/", accessibleFrom: "/variamos_languages/", target: "newWindow", allowedPermissions: [], }, { title: "Report a problem", - location: `https://github.com/variamosple/VariaMosPLE/issues/new`, + location: "https://github.com/variamosple/VariaMosPLE/issues/new", accessibleFrom: "/", target: "newWindow", allowedPermissions: [], }, { title: "Issues", - location: `https://github.com/variamosple/VariaMosPLE/issues/`, + location: "https://github.com/variamosple/VariaMosPLE/issues/", accessibleFrom: "/", target: "newWindow", allowedPermissions: [], }, { title: "Report a problem", - location: `https://github.com/variamosple/VariaMosAdmin/issues/new`, + location: "https://github.com/variamosple/VariaMosAdmin/issues/new", accessibleFrom: "/variamos_admin/", target: "newWindow", allowedPermissions: ["languages::create", "product-lines::create"], }, { title: "Issues", - location: `https://github.com/variamosple/VariaMosAdmin/issues/`, + location: "https://github.com/variamosple/VariaMosAdmin/issues/", accessibleFrom: "/variamos_admin/", target: "newWindow", allowedPermissions: ["languages::create", "product-lines::create"], @@ -149,9 +149,13 @@ export function createConfigurationRouter(): Router { const referer = req.headers.referer || ""; const hasAdminSubpath = referer.includes("/variamos_admin/"); - const myAccountOption = menuCopy.options?.find((opt) => opt.title === "My account"); + const myAccountOption = menuCopy.options?.find( + (opt) => opt.title === "My account", + ); if (myAccountOption) { - myAccountOption.location = hasAdminSubpath ? "/variamos_admin/#/my-account" : "/my-account"; + myAccountOption.location = hasAdminSubpath + ? "/variamos_admin/#/my-account" + : "/my-account"; } res.status(200).json(response.withResponse(menuCopy)); diff --git a/src/EntryPoints/CountriesV1Router.test.ts b/src/EntryPoints/CountriesV1Router.test.ts index 3adb053..193f2c5 100644 --- a/src/EntryPoints/CountriesV1Router.test.ts +++ b/src/EntryPoints/CountriesV1Router.test.ts @@ -1,16 +1,20 @@ +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createCountriesRouter } from "./CountriesV1Router"; -import { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { createCountriesRouter } from "./CountriesV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/Countries/UseCase/CountriesQueryUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ - isAuthenticated: (_req: express.Request, _res: express.Response, next: express.NextFunction) => { +vi.mock("@src/Domain/Countries/UseCase/CountriesQueryUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ + isAuthenticated: ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); @@ -19,7 +23,7 @@ interface CountriesApiResponse { data: string[]; } -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; describe("CountriesV1Router Integration Tests", () => { let app: express.Application; @@ -27,43 +31,53 @@ describe("CountriesV1Router Integration Tests", () => { beforeAll(() => { app = express(); app.use(express.json()); - const mockCountriesUseCase = new CountriesQueryUseCase(mock()); + const mockCountriesUseCase = new CountriesQueryUseCase( + mock(), + ); app.use("/v1/countries", createCountriesRouter(mockCountriesUseCase)); }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/countries", () => { it("should return 200 and list of countries on success", async () => { const mockCountries = ["Colombia", "France", "Spain"]; - const expectedResponse = new ResponseModel("getCountries").withResponse(mockCountries); - - (CountriesQueryUseCase.prototype.getCountries as jest.Mock).mockResolvedValue( - expectedResponse, + const expectedResponse = new ResponseModel("getCountries").withResponse( + mockCountries, ); + ( + CountriesQueryUseCase.prototype.getCountries as vi.Mock + ).mockResolvedValue(expectedResponse); + const response = await supertest(app).get("/v1/countries"); expect(response.status).toBe(HttpStatusCodes.OK); const body = response.body as CountriesApiResponse; expect(body.data).toEqual(mockCountries); - expect(CountriesQueryUseCase.prototype.getCountries).toHaveBeenCalledTimes(1); - expect(CountriesQueryUseCase.prototype.getCountries).toHaveBeenLastCalledWith( + expect( + CountriesQueryUseCase.prototype.getCountries, + ).toHaveBeenCalledTimes(1); + expect( + CountriesQueryUseCase.prototype.getCountries, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "getCountries" }), ); }); it("should return 500 when CountriesQueryUseCase throws an exception", async () => { - (CountriesQueryUseCase.prototype.getCountries as jest.Mock).mockRejectedValue( - new Error("Database error"), - ); + ( + CountriesQueryUseCase.prototype.getCountries as vi.Mock + ).mockRejectedValue(new Error("Database error")); const response = await supertest(app).get("/v1/countries"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "getCountries" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "getCountries" }), + ); }); }); }); diff --git a/src/EntryPoints/CountriesV1Router.ts b/src/EntryPoints/CountriesV1Router.ts index 9bdaff7..4daa8c8 100644 --- a/src/EntryPoints/CountriesV1Router.ts +++ b/src/EntryPoints/CountriesV1Router.ts @@ -1,17 +1,19 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { isAuthenticated } from "@variamosple/variamos-security"; import { Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const COUNTRIES_V1_ROUTE = "/v1/countries"; -export function createCountriesRouter(countriesQueryUseCase: CountriesQueryUseCase): Router { +export function createCountriesRouter( + countriesQueryUseCase: CountriesQueryUseCase, +): Router { const countriesV1Router = Router(); countriesV1Router.get("/", isAuthenticated, async (_, res) => { diff --git a/src/EntryPoints/MetricsV1Router.test.ts b/src/EntryPoints/MetricsV1Router.test.ts index ee7a72d..71984da 100644 --- a/src/EntryPoints/MetricsV1Router.test.ts +++ b/src/EntryPoints/MetricsV1Router.test.ts @@ -1,18 +1,23 @@ +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { Metric } from "@src/Domain/Metrics/Entity/Metric.js"; +import { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createMetricsRouter } from "./MetricsV1Router"; -import { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Metric } from "@src/Domain/Metrics/Entity/Metric"; +import { createMetricsRouter } from "./MetricsV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/Metrics/UseCase/MetricsQueryUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/Metrics/UseCase/MetricsQueryUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: - () => (_req: express.Request, _res: express.Response, next: express.NextFunction) => { + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); @@ -32,7 +37,7 @@ interface SingleMetricApiResponse { data: SerializedMetric; } -import { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository"; +import type { IMetricsRepository } from "@src/Domain/Metrics/Repository/IMetricsRepository.js"; describe("MetricsV1Router Integration Tests", () => { let app: express.Application; @@ -40,12 +45,14 @@ describe("MetricsV1Router Integration Tests", () => { beforeAll(() => { app = express(); app.use(express.json()); - const mockMetricsUseCase = new MetricsQueryUseCase(mock()); + const mockMetricsUseCase = new MetricsQueryUseCase( + mock(), + ); app.use("/v1/metrics", createMetricsRouter(mockMetricsUseCase)); }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/metrics", () => { @@ -58,9 +65,13 @@ describe("MetricsV1Router Integration Tests", () => { .setDefaultFilter("") .build(), ]; - const expectedResponse = new ResponseModel("getMetrics").withResponse(mockMetrics); + const expectedResponse = new ResponseModel("getMetrics").withResponse( + mockMetrics, + ); - (MetricsQueryUseCase.prototype.getMetrics as jest.Mock).mockResolvedValue(expectedResponse); + (MetricsQueryUseCase.prototype.getMetrics as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/metrics"); @@ -74,14 +85,16 @@ describe("MetricsV1Router Integration Tests", () => { }); it("should return 500 when MetricsQueryUseCase throws an exception", async () => { - (MetricsQueryUseCase.prototype.getMetrics as jest.Mock).mockRejectedValue( + (MetricsQueryUseCase.prototype.getMetrics as vi.Mock).mockRejectedValue( new Error("Query error"), ); const response = await supertest(app).get("/v1/metrics"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "getMetrics" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "getMetrics" }), + ); }); }); @@ -93,9 +106,13 @@ describe("MetricsV1Router Integration Tests", () => { .setChartType("bar") .setDefaultFilter("") .build(); - const expectedResponse = new ResponseModel("queryMetric").withResponse(mockMetric); + const expectedResponse = new ResponseModel("queryMetric").withResponse( + mockMetric, + ); - (MetricsQueryUseCase.prototype.queryMetric as jest.Mock).mockResolvedValue(expectedResponse); + (MetricsQueryUseCase.prototype.queryMetric as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .get("/v1/metrics/metric-1") @@ -104,21 +121,27 @@ describe("MetricsV1Router Integration Tests", () => { expect(response.status).toBe(HttpStatusCodes.OK); const body = response.body as SingleMetricApiResponse; expect(body.data.id).toBe("metric-1"); - expect(MetricsQueryUseCase.prototype.queryMetric).toHaveBeenCalledTimes(1); - expect(MetricsQueryUseCase.prototype.queryMetric).toHaveBeenLastCalledWith( + expect(MetricsQueryUseCase.prototype.queryMetric).toHaveBeenCalledTimes( + 1, + ); + expect( + MetricsQueryUseCase.prototype.queryMetric, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "queryMetric" }), ); }); it("should return 500 when queryMetric throws an exception", async () => { - (MetricsQueryUseCase.prototype.queryMetric as jest.Mock).mockRejectedValue( + (MetricsQueryUseCase.prototype.queryMetric as vi.Mock).mockRejectedValue( new Error("Query error"), ); const response = await supertest(app).get("/v1/metrics/metric-1"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "queryMetric" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "queryMetric" }), + ); }); }); }); diff --git a/src/EntryPoints/MetricsV1Router.ts b/src/EntryPoints/MetricsV1Router.ts index b245e64..fdc3bee 100644 --- a/src/EntryPoints/MetricsV1Router.ts +++ b/src/EntryPoints/MetricsV1Router.ts @@ -1,39 +1,45 @@ -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter"; -import { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter.js"; +import type { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const METRICS_V1_ROUTE = "/v1/metrics"; -export function createMetricsRouter(metricsQueryUseCase: MetricsQueryUseCase): Router { +export function createMetricsRouter( + metricsQueryUseCase: MetricsQueryUseCase, +): Router { const metricsV1Router = Router(); - metricsV1Router.get("/", hasPermissions(["metrics::query"]), async (_, res) => { - const transactionId = "getMetrics"; + metricsV1Router.get( + "/", + hasPermissions(["metrics::query"]), + async (_, res) => { + const transactionId = "getMetrics"; - try { - const request = new RequestModel(transactionId); - const response = await metricsQueryUseCase.getMetrics(request); + try { + const request = new RequestModel(transactionId); + const response = await metricsQueryUseCase.getMetrics(request); - const status = mapDomainErrorToHttpStatus(response.errorCode); - res.status(status).json(response); - } catch (error) { - logger.err(error); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); - } - }); + const status = mapDomainErrorToHttpStatus(response.errorCode); + res.status(status).json(response); + } catch (error) { + logger.err(error); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); + } + }, + ); metricsV1Router.get( "/:metricId", diff --git a/src/EntryPoints/MicroServicesV1Router.test.ts b/src/EntryPoints/MicroServicesV1Router.test.ts index a98e42e..0b92cb3 100644 --- a/src/EntryPoints/MicroServicesV1Router.test.ts +++ b/src/EntryPoints/MicroServicesV1Router.test.ts @@ -1,26 +1,31 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { Readable } from "node:stream"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; +import { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createMicroServicesRouter } from "./MicroServicesV1Router"; -import { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"; -import { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Readable } from "stream"; +import { createMicroServicesRouter } from "./MicroServicesV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"); -jest.mock("@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"); +vi.mock("@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: - () => (_req: express.Request, _res: express.Response, next: express.NextFunction) => { + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); -import { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository"; +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -28,7 +33,9 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { beforeAll(() => { app = express(); app.use(express.json()); - const mockQueryUseCase = new MicroServiceQueryUseCase(mock()); + const mockQueryUseCase = new MicroServiceQueryUseCase( + mock(), + ); const mockManagementUseCase = new MicroServiceManagementUseCase( mock(), ); @@ -39,23 +46,29 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/micro-services", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("queryMicroService").withResponse([]); - (MicroServiceQueryUseCase.prototype.queryMicroServices as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "queryMicroService", + ).withResponse([]); + ( + MicroServiceQueryUseCase.prototype.queryMicroServices as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/micro-services") .query({ pageNumber: 1, pageSize: 10, name: "test" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(MicroServiceQueryUseCase.prototype.queryMicroServices).toHaveBeenCalledTimes(1); - expect(MicroServiceQueryUseCase.prototype.queryMicroServices).toHaveBeenLastCalledWith( + expect( + MicroServiceQueryUseCase.prototype.queryMicroServices, + ).toHaveBeenCalledTimes(1); + expect( + MicroServiceQueryUseCase.prototype.queryMicroServices, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "queryMicroService" }), ); }); @@ -65,9 +78,9 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Query failed", ); - (MicroServiceQueryUseCase.prototype.queryMicroServices as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + MicroServiceQueryUseCase.prototype.queryMicroServices as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).get("/v1/micro-services"); @@ -75,9 +88,9 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when query throws an exception", async () => { - (MicroServiceQueryUseCase.prototype.queryMicroServices as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + MicroServiceQueryUseCase.prototype.queryMicroServices as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).get("/v1/micro-services"); @@ -90,16 +103,24 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { describe("PUT /v1/micro-services/:microserviceId/start", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("startMicroService").withResponse(null); - (MicroServiceManagementUseCase.prototype.startMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "startMicroService", + ).withResponse(null); + ( + MicroServiceManagementUseCase.prototype.startMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/start"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/start", + ); expect(response.status).toBe(HttpStatusCodes.OK); - expect(MicroServiceManagementUseCase.prototype.startMicroService).toHaveBeenCalledTimes(1); - expect(MicroServiceManagementUseCase.prototype.startMicroService).toHaveBeenLastCalledWith( + expect( + MicroServiceManagementUseCase.prototype.startMicroService, + ).toHaveBeenCalledTimes(1); + expect( + MicroServiceManagementUseCase.prototype.startMicroService, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "startMicroService" }), ); }); @@ -109,21 +130,25 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Start failed", ); - (MicroServiceManagementUseCase.prototype.startMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + MicroServiceManagementUseCase.prototype.startMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/start"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/start", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 500 when start throws an exception", async () => { - (MicroServiceManagementUseCase.prototype.startMicroService as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + MicroServiceManagementUseCase.prototype.startMicroService as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).put("/v1/micro-services/ms-123/start"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/start", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); expect(response.body).toEqual( @@ -134,40 +159,51 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { describe("PUT /v1/micro-services/:microserviceId/restart", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("restartMicroService").withResponse(null); - (MicroServiceManagementUseCase.prototype.restartMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "restartMicroService", + ).withResponse(null); + ( + MicroServiceManagementUseCase.prototype.restartMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/restart"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/restart", + ); expect(response.status).toBe(HttpStatusCodes.OK); - expect(MicroServiceManagementUseCase.prototype.restartMicroService).toHaveBeenCalledTimes(1); - expect(MicroServiceManagementUseCase.prototype.restartMicroService).toHaveBeenLastCalledWith( + expect( + MicroServiceManagementUseCase.prototype.restartMicroService, + ).toHaveBeenCalledTimes(1); + expect( + MicroServiceManagementUseCase.prototype.restartMicroService, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "restartMicroService" }), ); }); it("should return error status code when restart fails", async () => { - const expectedResponse = new ResponseModel("restartMicroService").withError( - DomainErrorCodes.INVALID_INPUT, - "Restart failed", - ); - (MicroServiceManagementUseCase.prototype.restartMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "restartMicroService", + ).withError(DomainErrorCodes.INVALID_INPUT, "Restart failed"); + ( + MicroServiceManagementUseCase.prototype.restartMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/restart"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/restart", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 500 when restart throws an exception", async () => { - (MicroServiceManagementUseCase.prototype.restartMicroService as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + MicroServiceManagementUseCase.prototype.restartMicroService as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).put("/v1/micro-services/ms-123/restart"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/restart", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); expect(response.body).toEqual( @@ -178,16 +214,24 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { describe("PUT /v1/micro-services/:microserviceId/stop", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("stopMicroService").withResponse(null); - (MicroServiceManagementUseCase.prototype.stopMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "stopMicroService", + ).withResponse(null); + ( + MicroServiceManagementUseCase.prototype.stopMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/stop"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/stop", + ); expect(response.status).toBe(HttpStatusCodes.OK); - expect(MicroServiceManagementUseCase.prototype.stopMicroService).toHaveBeenCalledTimes(1); - expect(MicroServiceManagementUseCase.prototype.stopMicroService).toHaveBeenLastCalledWith( + expect( + MicroServiceManagementUseCase.prototype.stopMicroService, + ).toHaveBeenCalledTimes(1); + expect( + MicroServiceManagementUseCase.prototype.stopMicroService, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "stopMicroService" }), ); }); @@ -197,24 +241,30 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Stop failed", ); - (MicroServiceManagementUseCase.prototype.stopMicroService as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + MicroServiceManagementUseCase.prototype.stopMicroService as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/micro-services/ms-123/stop"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/stop", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 500 when stop throws an exception", async () => { - (MicroServiceManagementUseCase.prototype.stopMicroService as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + MicroServiceManagementUseCase.prototype.stopMicroService as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).put("/v1/micro-services/ms-123/stop"); + const response = await supertest(app).put( + "/v1/micro-services/ms-123/stop", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "stopMicroService" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "stopMicroService" }), + ); }); }); @@ -228,12 +278,12 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }, }); - const expectedResponse = new ResponseModel("watchMicroServiceLogs").withResponse( - mockStream, - ); - (MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "watchMicroServiceLogs", + ).withResponse(mockStream); + ( + MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/micro-services/ms-123/logs/watch") @@ -248,28 +298,31 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }); it("should return error code when use case watchMicroServiceLogs returns error code", async () => { - const expectedResponse = new ResponseModel("watchMicroServiceLogs").withError( - DomainErrorCodes.INVALID_INPUT, - "Failed to watch logs", - ); - (MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "watchMicroServiceLogs", + ).withError(DomainErrorCodes.INVALID_INPUT, "Failed to watch logs"); + ( + MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).get("/v1/micro-services/ms-123/logs/watch"); + const response = await supertest(app).get( + "/v1/micro-services/ms-123/logs/watch", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 404 when no logs stream is returned", async () => { - const expectedResponse = new ResponseModel("watchMicroServiceLogs").withResponse( - null, - ); - (MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "watchMicroServiceLogs", + ).withResponse(null); + ( + MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).get("/v1/micro-services/ms-123/logs/watch"); + const response = await supertest(app).get( + "/v1/micro-services/ms-123/logs/watch", + ); expect(response.status).toBe(HttpStatusCodes.NOT_FOUND); }); @@ -281,12 +334,12 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }, }); - const expectedResponse = new ResponseModel("watchMicroServiceLogs").withResponse( - mockStream, - ); - (MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "watchMicroServiceLogs", + ).withResponse(mockStream); + ( + MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/micro-services/ms-123/logs/watch") @@ -296,11 +349,13 @@ describe("MicroServicesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when logs watch throws an exception", async () => { - (MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + MicroServiceQueryUseCase.prototype.watchMicroServiceLogs as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).get("/v1/micro-services/ms-123/logs/watch"); + const response = await supertest(app).get( + "/v1/micro-services/ms-123/logs/watch", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); expect(response.body).toEqual( diff --git a/src/EntryPoints/MicroServicesV1Router.ts b/src/EntryPoints/MicroServicesV1Router.ts index 206b543..59b9527 100644 --- a/src/EntryPoints/MicroServicesV1Router.ts +++ b/src/EntryPoints/MicroServicesV1Router.ts @@ -1,14 +1,14 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter"; -import { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"; -import { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; +import type { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; +import type { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const MICRO_SERVICES_V1_ROUTE = "/v1/micro-services"; @@ -18,32 +18,40 @@ export function createMicroServicesRouter( ): Router { const microServicesV1Router = Router(); - microServicesV1Router.get("/", hasPermissions(["micro-services::query"]), async (req, res) => { - const transactionId = "queryMicroService"; - const { pageNumber, pageSize, name = null } = req.query; - - try { - const filter: MicroServiceFilter = MicroServiceFilter.builder() - .setName(name as string) - .setPageNumber(Number(pageNumber)) - .setPageSize(Number(pageSize)) - .build(); - - const request = new RequestModel(transactionId, filter); - const response = await microServiceQueryUseCase.queryMicroServices(request); - - const status = mapDomainErrorToHttpStatus(response.errorCode); - res.status(status).json(response); - } catch (error) { - logger.err(error); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); - } - }); + microServicesV1Router.get( + "/", + hasPermissions(["micro-services::query"]), + async (req, res) => { + const transactionId = "queryMicroService"; + const { pageNumber, pageSize, name = null } = req.query; + + try { + const filter: MicroServiceFilter = MicroServiceFilter.builder() + .setName(name as string) + .setPageNumber(Number(pageNumber)) + .setPageSize(Number(pageSize)) + .build(); + + const request = new RequestModel( + transactionId, + filter, + ); + const response = + await microServiceQueryUseCase.queryMicroServices(request); + + const status = mapDomainErrorToHttpStatus(response.errorCode); + res.status(status).json(response); + } catch (error) { + logger.err(error); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); + } + }, + ); microServicesV1Router.put( "/:microserviceId/start", @@ -54,7 +62,8 @@ export function createMicroServicesRouter( try { const request = new RequestModel(transactionId, microserviceId); - const response = await microServiceManagementUseCase.startMicroService(request); + const response = + await microServiceManagementUseCase.startMicroService(request); const status = mapDomainErrorToHttpStatus(response.errorCode); res.status(status).json(response); @@ -79,7 +88,8 @@ export function createMicroServicesRouter( try { const request = new RequestModel(transactionId, microserviceId); - const response = await microServiceManagementUseCase.restartMicroService(request); + const response = + await microServiceManagementUseCase.restartMicroService(request); const status = mapDomainErrorToHttpStatus(response.errorCode); res.status(status).json(response); @@ -104,7 +114,8 @@ export function createMicroServicesRouter( try { const request = new RequestModel(transactionId, microserviceId); - const response = await microServiceManagementUseCase.stopMicroService(request); + const response = + await microServiceManagementUseCase.stopMicroService(request); const status = mapDomainErrorToHttpStatus(response.errorCode); res.status(status).json(response); @@ -130,10 +141,13 @@ export function createMicroServicesRouter( try { const request = new RequestModel(transactionId, microserviceId); - const response = await microServiceQueryUseCase.watchMicroServiceLogs(request); + const response = + await microServiceQueryUseCase.watchMicroServiceLogs(request); if (response.errorCode) { - res.status(mapDomainErrorToHttpStatus(response.errorCode)).json(response); + res + .status(mapDomainErrorToHttpStatus(response.errorCode)) + .json(response); return; } @@ -143,7 +157,7 @@ export function createMicroServicesRouter( .json( response.withError( DomainErrorCodes.ENTITY_NOT_FOUND, - "No Logs found for microservice with id: " + microserviceId, + `No Logs found for microservice with id: ${microserviceId}`, ), ); return; diff --git a/src/EntryPoints/PermissionsV1Router.test.ts b/src/EntryPoints/PermissionsV1Router.test.ts index f2b8dca..716ebec 100644 --- a/src/EntryPoints/PermissionsV1Router.test.ts +++ b/src/EntryPoints/PermissionsV1Router.test.ts @@ -1,24 +1,29 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createPermissionsRouter } from "./PermissionsV1Router"; -import { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; +import { createPermissionsRouter } from "./PermissionsV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/Permission/UseCase/PermissionUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/Permission/UseCase/PermissionUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: - () => (_req: express.Request, _res: express.Response, next: express.NextFunction) => { + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); -import { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository"; +import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -26,28 +31,36 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { beforeAll(() => { app = express(); app.use(express.json()); - const mockPermissionUseCase = new PermissionUseCase(mock()); + const mockPermissionUseCase = new PermissionUseCase( + mock(), + ); app.use("/v1/permissions", createPermissionsRouter(mockPermissionUseCase)); }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/permissions", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("queryPermissions").withResponse([]); - (PermissionUseCase.prototype.queryPermissions as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "queryPermissions", + ).withResponse([]); + ( + PermissionUseCase.prototype.queryPermissions as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/permissions") .query({ pageNumber: 1, pageSize: 10 }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(PermissionUseCase.prototype.queryPermissions).toHaveBeenCalledTimes(1); - expect(PermissionUseCase.prototype.queryPermissions).toHaveBeenLastCalledWith( + expect( + PermissionUseCase.prototype.queryPermissions, + ).toHaveBeenCalledTimes(1); + expect( + PermissionUseCase.prototype.queryPermissions, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "queryPermissions" }), ); }); @@ -57,9 +70,9 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Query failed", ); - (PermissionUseCase.prototype.queryPermissions as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + PermissionUseCase.prototype.queryPermissions as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).get("/v1/permissions"); @@ -67,30 +80,40 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when query throws an exception", async () => { - (PermissionUseCase.prototype.queryPermissions as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + PermissionUseCase.prototype.queryPermissions as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).get("/v1/permissions"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "queryPermissions" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "queryPermissions" }), + ); }); }); describe("POST /v1/permissions", () => { it("should return 200 on success", async () => { const mockPerm = new Permission(1, "test::perm"); - const expectedResponse = new ResponseModel("createPermission").withResponse(mockPerm); - (PermissionUseCase.prototype.createPermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "createPermission", + ).withResponse(mockPerm); + ( + PermissionUseCase.prototype.createPermission as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).post("/v1/permissions").send({ name: "test::perm" }); + const response = await supertest(app) + .post("/v1/permissions") + .send({ name: "test::perm" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(PermissionUseCase.prototype.createPermission).toHaveBeenCalledTimes(1); - expect(PermissionUseCase.prototype.createPermission).toHaveBeenLastCalledWith( + expect( + PermissionUseCase.prototype.createPermission, + ).toHaveBeenCalledTimes(1); + expect( + PermissionUseCase.prototype.createPermission, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "createPermission" }), ); }); @@ -106,9 +129,9 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.DUPLICATE_ENTITY, "Conflict", ); - (PermissionUseCase.prototype.createPermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + PermissionUseCase.prototype.createPermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/v1/permissions") @@ -118,37 +141,47 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when create throws an exception", async () => { - (PermissionUseCase.prototype.createPermission as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + PermissionUseCase.prototype.createPermission as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app) .post("/v1/permissions") .send({ name: "users::exception" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "createPermission" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "createPermission" }), + ); }); }); describe("DELETE /v1/permissions/:permissionId", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("deletePermission").withResponse(null); - (PermissionUseCase.prototype.deletePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "deletePermission", + ).withResponse(null); + ( + PermissionUseCase.prototype.deletePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).delete("/v1/permissions/123"); expect(response.status).toBe(HttpStatusCodes.OK); - expect(PermissionUseCase.prototype.deletePermission).toHaveBeenCalledTimes(1); - expect(PermissionUseCase.prototype.deletePermission).toHaveBeenLastCalledWith( + expect( + PermissionUseCase.prototype.deletePermission, + ).toHaveBeenCalledTimes(1); + expect( + PermissionUseCase.prototype.deletePermission, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "deletePermission" }), ); }); it("should return 400 when permissionId is invalid", async () => { - const response = await supertest(app).delete("/v1/permissions/invalid-id"); + const response = await supertest(app).delete( + "/v1/permissions/invalid-id", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); @@ -158,9 +191,9 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (PermissionUseCase.prototype.deletePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + PermissionUseCase.prototype.deletePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).delete("/v1/permissions/123"); @@ -168,22 +201,28 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when delete throws an exception", async () => { - (PermissionUseCase.prototype.deletePermission as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + PermissionUseCase.prototype.deletePermission as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).delete("/v1/permissions/123"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "deletePermission" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "deletePermission" }), + ); }); }); describe("GET /v1/permissions/:permissionId", () => { it("should return 200 on success", async () => { const mockPerm = new Permission(123, "test::perm"); - const expectedResponse = new ResponseModel("queryPermissionById").withResponse(mockPerm); - (PermissionUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel( + "queryPermissionById", + ).withResponse(mockPerm); + (PermissionUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/permissions/123"); @@ -201,11 +240,12 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { }); it("should return error status code when queryById fails", async () => { - const expectedResponse = new ResponseModel("queryPermissionById").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "Not found", + const expectedResponse = new ResponseModel( + "queryPermissionById", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Not found"); + (PermissionUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, ); - (PermissionUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); const response = await supertest(app).get("/v1/permissions/123"); @@ -213,7 +253,7 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when queryById throws an exception", async () => { - (PermissionUseCase.prototype.queryById as jest.Mock).mockRejectedValue( + (PermissionUseCase.prototype.queryById as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -229,18 +269,24 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { describe("PUT /v1/permissions/:permissionId", () => { it("should return 200 on success", async () => { const mockPerm = new Permission(123, "updated::perm"); - const expectedResponse = new ResponseModel("updatePermission").withResponse(mockPerm); - (PermissionUseCase.prototype.updatePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "updatePermission", + ).withResponse(mockPerm); + ( + PermissionUseCase.prototype.updatePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .put("/v1/permissions/123") .send({ name: "updated::perm" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(PermissionUseCase.prototype.updatePermission).toHaveBeenCalledTimes(1); - expect(PermissionUseCase.prototype.updatePermission).toHaveBeenLastCalledWith( + expect( + PermissionUseCase.prototype.updatePermission, + ).toHaveBeenCalledTimes(1); + expect( + PermissionUseCase.prototype.updatePermission, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "updatePermission" }), ); }); @@ -264,24 +310,30 @@ describe("PermissionsV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (PermissionUseCase.prototype.updatePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + ( + PermissionUseCase.prototype.updatePermission as vi.Mock + ).mockResolvedValue(expectedResponse); - const response = await supertest(app).put("/v1/permissions/123").send({ name: "test::perm" }); + const response = await supertest(app) + .put("/v1/permissions/123") + .send({ name: "test::perm" }); expect(response.status).toBe(HttpStatusCodes.NOT_FOUND); }); it("should return 500 when update throws an exception", async () => { - (PermissionUseCase.prototype.updatePermission as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + PermissionUseCase.prototype.updatePermission as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).put("/v1/permissions/123").send({ name: "test::perm" }); + const response = await supertest(app) + .put("/v1/permissions/123") + .send({ name: "test::perm" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "updatePermission" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "updatePermission" }), + ); }); }); }); diff --git a/src/EntryPoints/PermissionsV1Router.ts b/src/EntryPoints/PermissionsV1Router.ts index c5ebfac..9861fb3 100644 --- a/src/EntryPoints/PermissionsV1Router.ts +++ b/src/EntryPoints/PermissionsV1Router.ts @@ -1,90 +1,103 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Permission } from "@src/Domain/Permission/Entity/Permission"; -import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter"; -import { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; +import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; +import type { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const PERMISSIONS_V1_ROUTE = "/v1/permissions"; -export function createPermissionsRouter(permissionUseCase: PermissionUseCase): Router { +export function createPermissionsRouter( + permissionUseCase: PermissionUseCase, +): Router { const permissionsV1Router = Router(); - permissionsV1Router.get("/", hasPermissions(["permissions::query"]), async (req, res) => { - const transactionId = "queryPermissions"; - const { pageNumber, pageSize, name = null } = req.query; - try { - const filter: PermissionFilter = PermissionFilter.builder() - .setName(name as string) - .setPageNumber(Number(pageNumber)) - .setPageSize(Number(pageSize)) - .build(); - - const request = new RequestModel(transactionId, filter); - const response = await permissionUseCase.queryPermissions(request); - - const status = mapDomainErrorToHttpStatus(response.errorCode); - res.status(status).json(response); - } catch (error) { - logger.err(error); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); - } - }); - - permissionsV1Router.post("/", hasPermissions(["permissions::create"]), async (req, res) => { - const transactionId = "createPermission"; - const { name } = req.body as { name?: string }; - try { - if (!name) { - return res - .status(HttpStatusCodes.BAD_REQUEST) - .json( - new ResponseModel(transactionId).withError( - DomainErrorCodes.INVALID_INPUT, - "name is required.", - ), - ); + permissionsV1Router.get( + "/", + hasPermissions(["permissions::query"]), + async (req, res) => { + const transactionId = "queryPermissions"; + const { pageNumber, pageSize, name = null } = req.query; + try { + const filter: PermissionFilter = PermissionFilter.builder() + .setName(name as string) + .setPageNumber(Number(pageNumber)) + .setPageSize(Number(pageSize)) + .build(); + + const request = new RequestModel( + transactionId, + filter, + ); + const response = await permissionUseCase.queryPermissions(request); + + const status = mapDomainErrorToHttpStatus(response.errorCode); + res.status(status).json(response); + } catch (error) { + logger.err(error); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); } + }, + ); - let permission: Permission; + permissionsV1Router.post( + "/", + hasPermissions(["permissions::create"]), + async (req, res) => { + const transactionId = "createPermission"; + const { name } = req.body as { name?: string }; try { - permission = new Permission(null, name); + if (!name) { + return res + .status(HttpStatusCodes.BAD_REQUEST) + .json( + new ResponseModel(transactionId).withError( + DomainErrorCodes.INVALID_INPUT, + "name is required.", + ), + ); + } + + let permission: Permission; + try { + permission = new Permission(null, name); + } catch (error) { + return res + .status(HttpStatusCodes.BAD_REQUEST) + .json( + new ResponseModel(transactionId).withError( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ), + ); + } + + const request = new RequestModel(transactionId, permission); + const response = await permissionUseCase.createPermission(request); + + const status = mapDomainErrorToHttpStatus(response.errorCode); + res.status(status).json(response); } catch (error) { - return res - .status(HttpStatusCodes.BAD_REQUEST) - .json( - new ResponseModel(transactionId).withError( - DomainErrorCodes.INVALID_INPUT, - (error as Error).message, - ), - ); + logger.err(error); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); } - - const request = new RequestModel(transactionId, permission); - const response = await permissionUseCase.createPermission(request); - - const status = mapDomainErrorToHttpStatus(response.errorCode); - res.status(status).json(response); - } catch (error) { - logger.err(error); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); - } - }); + }, + ); permissionsV1Router.delete( "/:permissionId", @@ -104,7 +117,10 @@ export function createPermissionsRouter(permissionUseCase: PermissionUseCase): R ); } - const request = new RequestModel(transactionId, Number.parseInt(permissionId)); + const request = new RequestModel( + transactionId, + Number.parseInt(permissionId), + ); const response = await permissionUseCase.deletePermission(request); const status = mapDomainErrorToHttpStatus(response.errorCode); @@ -140,7 +156,10 @@ export function createPermissionsRouter(permissionUseCase: PermissionUseCase): R ); } - const request = new RequestModel(transactionId, Number.parseInt(permissionId)); + const request = new RequestModel( + transactionId, + Number.parseInt(permissionId), + ); const response = await permissionUseCase.queryById(request); const status = mapDomainErrorToHttpStatus(response.errorCode); diff --git a/src/EntryPoints/RolePermissionsV1Router.test.ts b/src/EntryPoints/RolePermissionsV1Router.test.ts index e6d7087..a8c263f 100644 --- a/src/EntryPoints/RolePermissionsV1Router.test.ts +++ b/src/EntryPoints/RolePermissionsV1Router.test.ts @@ -1,24 +1,29 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; +import { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createRolePermissionsRouter } from "./RolePermissionsV1Router"; -import { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RolePermission } from "@src/Domain/Role/Entity/RolePermission"; +import { createRolePermissionsRouter } from "./RolePermissionsV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/Role/UseCase/RolePermissionUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/Role/UseCase/RolePermissionUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: - () => (_req: express.Request, _res: express.Response, next: express.NextFunction) => { + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); -import { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository"; +import type { IRolePermissionRepository } from "@src/Domain/Role/Repository/IRolePermissionRepository.js"; describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -26,7 +31,9 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => beforeAll(() => { app = express(); app.use(express.json()); - const mockRolePermissionUseCase = new RolePermissionUseCase(mock()); + const mockRolePermissionUseCase = new RolePermissionUseCase( + mock(), + ); app.use( "/v1/roles/:roleId/permissions", createRolePermissionsRouter(mockRolePermissionUseCase), @@ -34,41 +41,48 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/roles/:roleId/permissions", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("queryRolePermissions").withResponse([]); - (RolePermissionUseCase.prototype.queryRolePermissions as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "queryRolePermissions", + ).withResponse([]); + ( + RolePermissionUseCase.prototype.queryRolePermissions as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/roles/1/permissions") .query({ pageNumber: 1, pageSize: 10 }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(RolePermissionUseCase.prototype.queryRolePermissions).toHaveBeenCalledTimes(1); - expect(RolePermissionUseCase.prototype.queryRolePermissions).toHaveBeenLastCalledWith( + expect( + RolePermissionUseCase.prototype.queryRolePermissions, + ).toHaveBeenCalledTimes(1); + expect( + RolePermissionUseCase.prototype.queryRolePermissions, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "queryRolePermissions" }), ); }); it("should return 400 when roleId is invalid", async () => { - const response = await supertest(app).get("/v1/roles/invalid-id/permissions"); + const response = await supertest(app).get( + "/v1/roles/invalid-id/permissions", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return error status code when query fails", async () => { - const expectedResponse = new ResponseModel("queryRolePermissions").withError( - DomainErrorCodes.INVALID_INPUT, - "Query failed", - ); - (RolePermissionUseCase.prototype.queryRolePermissions as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "queryRolePermissions", + ).withError(DomainErrorCodes.INVALID_INPUT, "Query failed"); + ( + RolePermissionUseCase.prototype.queryRolePermissions as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).get("/v1/roles/1/permissions"); @@ -76,9 +90,9 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => }); it("should return 500 when query throws an exception", async () => { - (RolePermissionUseCase.prototype.queryRolePermissions as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + RolePermissionUseCase.prototype.queryRolePermissions as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).get("/v1/roles/1/permissions"); @@ -92,18 +106,24 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => describe("POST /v1/roles/:roleId/permissions", () => { it("should return 201 on success", async () => { const mockRolePerm = new RolePermission(1, 2); - const expectedResponse = new ResponseModel("createRolePermission").withResponse(mockRolePerm); - (RolePermissionUseCase.prototype.createRolePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "createRolePermission", + ).withResponse(mockRolePerm); + ( + RolePermissionUseCase.prototype.createRolePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/v1/roles/1/permissions") .send({ permissionId: 2 }); expect(response.status).toBe(HttpStatusCodes.CREATED); - expect(RolePermissionUseCase.prototype.createRolePermission).toHaveBeenCalledTimes(1); - expect(RolePermissionUseCase.prototype.createRolePermission).toHaveBeenLastCalledWith( + expect( + RolePermissionUseCase.prototype.createRolePermission, + ).toHaveBeenCalledTimes(1); + expect( + RolePermissionUseCase.prototype.createRolePermission, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "createRolePermission" }), ); }); @@ -117,19 +137,20 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => }); it("should return 400 when permissionId is missing or invalid", async () => { - const response = await supertest(app).post("/v1/roles/1/permissions").send({}); + const response = await supertest(app) + .post("/v1/roles/1/permissions") + .send({}); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return error status code when create fails", async () => { - const expectedResponse = new ResponseModel("createRolePermission").withError( - DomainErrorCodes.DUPLICATE_ENTITY, - "Already exists", - ); - (RolePermissionUseCase.prototype.createRolePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "createRolePermission", + ).withError(DomainErrorCodes.DUPLICATE_ENTITY, "Already exists"); + ( + RolePermissionUseCase.prototype.createRolePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .post("/v1/roles/1/permissions") @@ -139,9 +160,9 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => }); it("should return 500 when create throws an exception", async () => { - (RolePermissionUseCase.prototype.createRolePermission as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + RolePermissionUseCase.prototype.createRolePermission as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app) .post("/v1/roles/1/permissions") @@ -156,40 +177,49 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => describe("DELETE /v1/roles/:roleId/permissions/:permissionId", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("deleteRolePermission").withResponse(null); - (RolePermissionUseCase.prototype.deleteRolePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "deleteRolePermission", + ).withResponse(null); + ( + RolePermissionUseCase.prototype.deleteRolePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).delete("/v1/roles/1/permissions/2"); expect(response.status).toBe(HttpStatusCodes.OK); - expect(RolePermissionUseCase.prototype.deleteRolePermission).toHaveBeenCalledTimes(1); - expect(RolePermissionUseCase.prototype.deleteRolePermission).toHaveBeenLastCalledWith( + expect( + RolePermissionUseCase.prototype.deleteRolePermission, + ).toHaveBeenCalledTimes(1); + expect( + RolePermissionUseCase.prototype.deleteRolePermission, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "deleteRolePermission" }), ); }); it("should return 400 when roleId is invalid", async () => { - const response = await supertest(app).delete("/v1/roles/invalid-id/permissions/2"); + const response = await supertest(app).delete( + "/v1/roles/invalid-id/permissions/2", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 400 when permissionId is invalid", async () => { - const response = await supertest(app).delete("/v1/roles/1/permissions/invalid-id"); + const response = await supertest(app).delete( + "/v1/roles/1/permissions/invalid-id", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return error status code when delete fails", async () => { - const expectedResponse = new ResponseModel("deleteRolePermission").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "Not found", - ); - (RolePermissionUseCase.prototype.deleteRolePermission as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "deleteRolePermission", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "Not found"); + ( + RolePermissionUseCase.prototype.deleteRolePermission as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app).delete("/v1/roles/1/permissions/2"); @@ -197,9 +227,9 @@ describe("RolePermissionsV1Router Integration Tests - Extended Coverage", () => }); it("should return 500 when delete throws an exception", async () => { - (RolePermissionUseCase.prototype.deleteRolePermission as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + RolePermissionUseCase.prototype.deleteRolePermission as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); const response = await supertest(app).delete("/v1/roles/1/permissions/2"); diff --git a/src/EntryPoints/RolePermissionsV1Router.ts b/src/EntryPoints/RolePermissionsV1Router.ts index 59d64eb..d0eb5a7 100644 --- a/src/EntryPoints/RolePermissionsV1Router.ts +++ b/src/EntryPoints/RolePermissionsV1Router.ts @@ -1,18 +1,20 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { RolePermission } from "@src/Domain/Role/Entity/RolePermission"; -import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter"; -import { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; +import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter.js"; +import type { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const ROLE_PERMISSIONS_V1_ROUTE = "/:roleId/permissions"; -export function createRolePermissionsRouter(rolePermissionUseCase: RolePermissionUseCase): Router { +export function createRolePermissionsRouter( + rolePermissionUseCase: RolePermissionUseCase, +): Router { const rolePermissionsV1Router = Router({ mergeParams: true }); rolePermissionsV1Router.get( @@ -40,8 +42,12 @@ export function createRolePermissionsRouter(rolePermissionUseCase: RolePermissio .setPageSize(Number(pageSize)) .build(); - const request = new RequestModel(transactionId, filter); - const response = await rolePermissionUseCase.queryRolePermissions(request); + const request = new RequestModel( + transactionId, + filter, + ); + const response = + await rolePermissionUseCase.queryRolePermissions(request); const status = mapDomainErrorToHttpStatus(response.errorCode); res.status(status).json(response); @@ -86,8 +92,12 @@ export function createRolePermissionsRouter(rolePermissionUseCase: RolePermissio Number.parseInt(permissionId), ); - const request = new RequestModel(transactionId, rolePermission); - const response = await rolePermissionUseCase.createRolePermission(request); + const request = new RequestModel( + transactionId, + rolePermission, + ); + const response = + await rolePermissionUseCase.createRolePermission(request); const status = response.errorCode ? mapDomainErrorToHttpStatus(response.errorCode) @@ -133,8 +143,12 @@ export function createRolePermissionsRouter(rolePermissionUseCase: RolePermissio Number.parseInt(permissionId), ); - const request = new RequestModel(transactionId, rolePermission); - const response = await rolePermissionUseCase.deleteRolePermission(request); + const request = new RequestModel( + transactionId, + rolePermission, + ); + const response = + await rolePermissionUseCase.deleteRolePermission(request); const status = mapDomainErrorToHttpStatus(response.errorCode); res.status(status).json(response); diff --git a/src/EntryPoints/RolesV1Router.test.ts b/src/EntryPoints/RolesV1Router.test.ts index 3b73cf6..f7a8553 100644 --- a/src/EntryPoints/RolesV1Router.test.ts +++ b/src/EntryPoints/RolesV1Router.test.ts @@ -1,26 +1,31 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; +import { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createRolesRouter } from "./RolesV1Router"; -import { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase"; -import { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Role } from "@src/Domain/Role/Entity/Role"; +import { createRolesRouter } from "./RolesV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/Role/UseCase/RoleQueryUseCase"); -jest.mock("@src/Domain/Role/UseCase/RoleManagementUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/Role/UseCase/RoleQueryUseCase"); +vi.mock("@src/Domain/Role/UseCase/RoleManagementUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: - () => (_req: express.Request, _res: express.Response, next: express.NextFunction) => { + () => + ( + _req: express.Request, + _res: express.Response, + next: express.NextFunction, + ) => { next(); }, })); -import { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository"; +import type { IRoleRepository } from "@src/Domain/Role/Repository/IRoleRepository.js"; describe("RolesV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -29,24 +34,34 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { app = express(); app.use(express.json()); const mockRoleQueryUseCase = new RoleQueryUseCase(mock()); - const mockRoleManagementUseCase = new RoleManagementUseCase(mock()); + const mockRoleManagementUseCase = new RoleManagementUseCase( + mock(), + ); const mockRolePermissionsRouter = express.Router(); app.use( "/v1/roles", - createRolesRouter(mockRoleManagementUseCase, mockRoleQueryUseCase, mockRolePermissionsRouter), + createRolesRouter( + mockRoleManagementUseCase, + mockRoleQueryUseCase, + mockRolePermissionsRouter, + ), ); }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/roles", () => { it("should return 200 on success", async () => { const expectedResponse = new ResponseModel("queryRoles").withResponse([]); - (RoleQueryUseCase.prototype.queryRoles as jest.Mock).mockResolvedValue(expectedResponse); + (RoleQueryUseCase.prototype.queryRoles as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).get("/v1/roles").query({ pageNumber: 1, pageSize: 10 }); + const response = await supertest(app) + .get("/v1/roles") + .query({ pageNumber: 1, pageSize: 10 }); expect(response.status).toBe(HttpStatusCodes.OK); expect(RoleQueryUseCase.prototype.queryRoles).toHaveBeenCalledTimes(1); @@ -60,7 +75,9 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Query failed", ); - (RoleQueryUseCase.prototype.queryRoles as jest.Mock).mockResolvedValue(expectedResponse); + (RoleQueryUseCase.prototype.queryRoles as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/roles"); @@ -68,28 +85,40 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when query throws an exception", async () => { - (RoleQueryUseCase.prototype.queryRoles as jest.Mock).mockRejectedValue( + (RoleQueryUseCase.prototype.queryRoles as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); const response = await supertest(app).get("/v1/roles"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "queryRoles" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "queryRoles" }), + ); }); }); describe("POST /v1/roles", () => { it("should return 201 on success", async () => { const mockRole = new Role(1, "Test role"); - const expectedResponse = new ResponseModel("createRole").withResponse(mockRole); - (RoleManagementUseCase.prototype.createRole as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("createRole").withResponse( + mockRole, + ); + (RoleManagementUseCase.prototype.createRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/roles").send({ name: "Test role" }); + const response = await supertest(app) + .post("/v1/roles") + .send({ name: "Test role" }); expect(response.status).toBe(HttpStatusCodes.CREATED); - expect(RoleManagementUseCase.prototype.createRole).toHaveBeenCalledTimes(1); - expect(RoleManagementUseCase.prototype.createRole).toHaveBeenLastCalledWith( + expect(RoleManagementUseCase.prototype.createRole).toHaveBeenCalledTimes( + 1, + ); + expect( + RoleManagementUseCase.prototype.createRole, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "createRole" }), ); }); @@ -105,35 +134,51 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.DUPLICATE_ENTITY, "Conflict", ); - (RoleManagementUseCase.prototype.createRole as jest.Mock).mockResolvedValue(expectedResponse); + (RoleManagementUseCase.prototype.createRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/roles").send({ name: "Conflict" }); + const response = await supertest(app) + .post("/v1/roles") + .send({ name: "Conflict" }); expect(response.status).toBe(HttpStatusCodes.CONFLICT); }); it("should return 500 when create throws an exception", async () => { - (RoleManagementUseCase.prototype.createRole as jest.Mock).mockRejectedValue( + (RoleManagementUseCase.prototype.createRole as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).post("/v1/roles").send({ name: "Exception" }); + const response = await supertest(app) + .post("/v1/roles") + .send({ name: "Exception" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "createRole" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "createRole" }), + ); }); }); describe("DELETE /v1/roles/:roleId", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("deleteRole").withResponse(null); - (RoleManagementUseCase.prototype.deleteRole as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("deleteRole").withResponse( + null, + ); + (RoleManagementUseCase.prototype.deleteRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).delete("/v1/roles/123"); expect(response.status).toBe(HttpStatusCodes.OK); - expect(RoleManagementUseCase.prototype.deleteRole).toHaveBeenCalledTimes(1); - expect(RoleManagementUseCase.prototype.deleteRole).toHaveBeenLastCalledWith( + expect(RoleManagementUseCase.prototype.deleteRole).toHaveBeenCalledTimes( + 1, + ); + expect( + RoleManagementUseCase.prototype.deleteRole, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "deleteRole" }), ); }); @@ -149,7 +194,9 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (RoleManagementUseCase.prototype.deleteRole as jest.Mock).mockResolvedValue(expectedResponse); + (RoleManagementUseCase.prototype.deleteRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).delete("/v1/roles/123"); @@ -157,22 +204,28 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when delete throws an exception", async () => { - (RoleManagementUseCase.prototype.deleteRole as jest.Mock).mockRejectedValue( + (RoleManagementUseCase.prototype.deleteRole as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); const response = await supertest(app).delete("/v1/roles/123"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "deleteRole" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "deleteRole" }), + ); }); }); describe("GET /v1/roles/:roleId", () => { it("should return 200 on success", async () => { const mockRole = new Role(123, "Test role"); - const expectedResponse = new ResponseModel("queryRoleById").withResponse(mockRole); - (RoleQueryUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("queryRoleById").withResponse( + mockRole, + ); + (RoleQueryUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/roles/123"); @@ -194,7 +247,9 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (RoleQueryUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); + (RoleQueryUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/roles/123"); @@ -202,34 +257,48 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when queryById throws an exception", async () => { - (RoleQueryUseCase.prototype.queryById as jest.Mock).mockRejectedValue( + (RoleQueryUseCase.prototype.queryById as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); const response = await supertest(app).get("/v1/roles/123"); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "queryRoleById" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "queryRoleById" }), + ); }); }); describe("PUT /v1/roles/:roleId", () => { it("should return 200 on success", async () => { const mockRole = new Role(123, "Updated role"); - const expectedResponse = new ResponseModel("updateRole").withResponse(mockRole); - (RoleManagementUseCase.prototype.updateRole as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("updateRole").withResponse( + mockRole, + ); + (RoleManagementUseCase.prototype.updateRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).put("/v1/roles/123").send({ name: "Updated role" }); + const response = await supertest(app) + .put("/v1/roles/123") + .send({ name: "Updated role" }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(RoleManagementUseCase.prototype.updateRole).toHaveBeenCalledTimes(1); - expect(RoleManagementUseCase.prototype.updateRole).toHaveBeenLastCalledWith( + expect(RoleManagementUseCase.prototype.updateRole).toHaveBeenCalledTimes( + 1, + ); + expect( + RoleManagementUseCase.prototype.updateRole, + ).toHaveBeenLastCalledWith( expect.objectContaining({ transactionId: "updateRole" }), ); }); it("should return 400 when roleId is invalid", async () => { - const response = await supertest(app).put("/v1/roles/invalid-id").send({ name: "Test" }); + const response = await supertest(app) + .put("/v1/roles/invalid-id") + .send({ name: "Test" }); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); @@ -245,22 +314,30 @@ describe("RolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (RoleManagementUseCase.prototype.updateRole as jest.Mock).mockResolvedValue(expectedResponse); + (RoleManagementUseCase.prototype.updateRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).put("/v1/roles/123").send({ name: "Test" }); + const response = await supertest(app) + .put("/v1/roles/123") + .send({ name: "Test" }); expect(response.status).toBe(HttpStatusCodes.NOT_FOUND); }); it("should return 500 when update throws an exception", async () => { - (RoleManagementUseCase.prototype.updateRole as jest.Mock).mockRejectedValue( + (RoleManagementUseCase.prototype.updateRole as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).put("/v1/roles/123").send({ name: "Test" }); + const response = await supertest(app) + .put("/v1/roles/123") + .send({ name: "Test" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); - expect(response.body).toEqual(expect.objectContaining({ transactionId: "updateRole" })); + expect(response.body).toEqual( + expect.objectContaining({ transactionId: "updateRole" }), + ); }); }); }); diff --git a/src/EntryPoints/RolesV1Router.ts b/src/EntryPoints/RolesV1Router.ts index b052f2b..349ee3f 100644 --- a/src/EntryPoints/RolesV1Router.ts +++ b/src/EntryPoints/RolesV1Router.ts @@ -1,16 +1,16 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Role } from "@src/Domain/Role/Entity/Role"; -import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter"; -import { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase"; -import { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Role } from "@src/Domain/Role/Entity/Role.js"; +import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter.js"; +import type { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; +import type { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { ROLE_PERMISSIONS_V1_ROUTE } from "./RolePermissionsV1Router"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ROLE_PERMISSIONS_V1_ROUTE } from "./RolePermissionsV1Router.js"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const ROLES_V1_ROUTE = "/v1/roles"; @@ -47,52 +47,56 @@ export function createRolesRouter( } }); - rolesV1Router.post("/", hasPermissions(["roles::create"]), async (req, res) => { - const transactionId = "createRole"; - const { name } = req.body as { name?: string }; - try { - if (!name) { - return res - .status(HttpStatusCodes.BAD_REQUEST) - .json( - new ResponseModel(transactionId).withError( - DomainErrorCodes.INVALID_INPUT, - "name is required.", - ), - ); - } - - let role: Role; + rolesV1Router.post( + "/", + hasPermissions(["roles::create"]), + async (req, res) => { + const transactionId = "createRole"; + const { name } = req.body as { name?: string }; try { - role = new Role(null, name); - } catch (error) { - return res - .status(HttpStatusCodes.BAD_REQUEST) - .json( - new ResponseModel(transactionId).withError( - DomainErrorCodes.INVALID_INPUT, - (error as Error).message, - ), - ); - } + if (!name) { + return res + .status(HttpStatusCodes.BAD_REQUEST) + .json( + new ResponseModel(transactionId).withError( + DomainErrorCodes.INVALID_INPUT, + "name is required.", + ), + ); + } - const request = new RequestModel(transactionId, role); - const response = await roleManagementUseCase.createRole(request); + let role: Role; + try { + role = new Role(null, name); + } catch (error) { + return res + .status(HttpStatusCodes.BAD_REQUEST) + .json( + new ResponseModel(transactionId).withError( + DomainErrorCodes.INVALID_INPUT, + (error as Error).message, + ), + ); + } - const status = response.errorCode - ? mapDomainErrorToHttpStatus(response.errorCode) - : HttpStatusCodes.CREATED; - res.status(status).json(response); - } catch (error) { - logger.err(error); - const response = new ResponseModel( - transactionId, - DomainErrorCodes.SYSTEM_ERROR, - "Internal Server Error", - ); - res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); - } - }); + const request = new RequestModel(transactionId, role); + const response = await roleManagementUseCase.createRole(request); + + const status = response.errorCode + ? mapDomainErrorToHttpStatus(response.errorCode) + : HttpStatusCodes.CREATED; + res.status(status).json(response); + } catch (error) { + logger.err(error); + const response = new ResponseModel( + transactionId, + DomainErrorCodes.SYSTEM_ERROR, + "Internal Server Error", + ); + res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(response); + } + }, + ); rolesV1Router.delete( "/:roleId", diff --git a/src/EntryPoints/UserRolesV1Router.test.ts b/src/EntryPoints/UserRolesV1Router.test.ts index c09a872..d338e5a 100644 --- a/src/EntryPoints/UserRolesV1Router.test.ts +++ b/src/EntryPoints/UserRolesV1Router.test.ts @@ -1,23 +1,23 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { UserRole } from "@src/Domain/User/Entity/UserRole.js"; +import { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createUserRolesRouter } from "./UserRolesV1Router"; -import { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { UserRole } from "@src/Domain/User/Entity/UserRole"; +import { createUserRolesRouter } from "./UserRolesV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; // Mock dependencies -jest.mock("@src/Domain/User/UseCase/UserRoleUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@src/Domain/User/UseCase/UserRoleUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: () => (_req: unknown, _res: unknown, next: () => void) => { next(); }, })); -import { IUserRoleRepository } from "@src/Domain/User/Repository/IUserRoleRepository"; +import type { IUserRoleRepository } from "@src/Domain/User/Repository/IUserRoleRepository.js"; describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -25,18 +25,27 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { beforeAll(() => { app = express(); app.use(express.json()); - const mockUserRoleUseCase = new UserRoleUseCase(mock()); - app.use("/v1/users/:userId/roles", createUserRolesRouter(mockUserRoleUseCase)); + const mockUserRoleUseCase = new UserRoleUseCase( + mock(), + ); + app.use( + "/v1/users/:userId/roles", + createUserRolesRouter(mockUserRoleUseCase), + ); }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("GET /v1/users/:userId/roles", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("queryUserRoles").withResponse([]); - (UserRoleUseCase.prototype.queryUserRoles as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("queryUserRoles").withResponse( + [], + ); + (UserRoleUseCase.prototype.queryUserRoles as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .get("/v1/users/user-123/roles") @@ -61,7 +70,9 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Query failed", ); - (UserRoleUseCase.prototype.queryUserRoles as jest.Mock).mockResolvedValue(expectedResponse); + (UserRoleUseCase.prototype.queryUserRoles as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/users/user-123/roles"); @@ -69,7 +80,7 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when query throws an exception", async () => { - (UserRoleUseCase.prototype.queryUserRoles as jest.Mock).mockRejectedValue( + (UserRoleUseCase.prototype.queryUserRoles as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -81,18 +92,24 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { describe("GET /v1/users/:userId/roles/details", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("queryUserRolesDetails").withResponse([]); - (UserRoleUseCase.prototype.queryUserRolesDetails as jest.Mock).mockResolvedValue( - expectedResponse, - ); + const expectedResponse = new ResponseModel( + "queryUserRolesDetails", + ).withResponse([]); + ( + UserRoleUseCase.prototype.queryUserRolesDetails as vi.Mock + ).mockResolvedValue(expectedResponse); const response = await supertest(app) .get("/v1/users/user-123/roles/details") .query({ pageNumber: 1, pageSize: 10 }); expect(response.status).toBe(HttpStatusCodes.OK); - expect(UserRoleUseCase.prototype.queryUserRolesDetails).toHaveBeenCalledTimes(1); - expect(UserRoleUseCase.prototype.queryUserRolesDetails).toHaveBeenCalledWith( + expect( + UserRoleUseCase.prototype.queryUserRolesDetails, + ).toHaveBeenCalledTimes(1); + expect( + UserRoleUseCase.prototype.queryUserRolesDetails, + ).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "queryUserRolesDetails" }), ); }); @@ -105,25 +122,28 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return error status code when query details fails", async () => { - const expectedResponse = new ResponseModel("queryUserRolesDetails").withError( - DomainErrorCodes.INVALID_INPUT, - "Query details failed", - ); - (UserRoleUseCase.prototype.queryUserRolesDetails as jest.Mock).mockResolvedValue( - expectedResponse, + const expectedResponse = new ResponseModel( + "queryUserRolesDetails", + ).withError(DomainErrorCodes.INVALID_INPUT, "Query details failed"); + ( + UserRoleUseCase.prototype.queryUserRolesDetails as vi.Mock + ).mockResolvedValue(expectedResponse); + + const response = await supertest(app).get( + "/v1/users/user-123/roles/details", ); - const response = await supertest(app).get("/v1/users/user-123/roles/details"); - expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 500 when query details throws an exception", async () => { - (UserRoleUseCase.prototype.queryUserRolesDetails as jest.Mock).mockRejectedValue( - new Error("Unexpected error"), - ); + ( + UserRoleUseCase.prototype.queryUserRolesDetails as vi.Mock + ).mockRejectedValue(new Error("Unexpected error")); - const response = await supertest(app).get("/v1/users/user-123/roles/details"); + const response = await supertest(app).get( + "/v1/users/user-123/roles/details", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); @@ -132,10 +152,16 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { describe("POST /v1/users/:userId/roles", () => { it("should return 201 on success", async () => { const mockUserRole = new UserRole("user-123", 2); - const expectedResponse = new ResponseModel("createUserRole").withResponse(mockUserRole); - (UserRoleUseCase.prototype.createUserRole as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("createUserRole").withResponse( + mockUserRole, + ); + (UserRoleUseCase.prototype.createUserRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/users/user-123/roles").send({ roleId: 2 }); + const response = await supertest(app) + .post("/v1/users/user-123/roles") + .send({ roleId: 2 }); expect(response.status).toBe(HttpStatusCodes.CREATED); expect(UserRoleUseCase.prototype.createUserRole).toHaveBeenCalledTimes(1); @@ -145,7 +171,9 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 400 when roleId is missing or invalid", async () => { - const response = await supertest(app).post("/v1/users/user-123/roles").send({}); + const response = await supertest(app) + .post("/v1/users/user-123/roles") + .send({}); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); @@ -172,19 +200,25 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.DUPLICATE_ENTITY, "Conflict", ); - (UserRoleUseCase.prototype.createUserRole as jest.Mock).mockResolvedValue(expectedResponse); + (UserRoleUseCase.prototype.createUserRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/users/user-123/roles").send({ roleId: 2 }); + const response = await supertest(app) + .post("/v1/users/user-123/roles") + .send({ roleId: 2 }); expect(response.status).toBe(HttpStatusCodes.CONFLICT); }); it("should return 500 when create throws an exception", async () => { - (UserRoleUseCase.prototype.createUserRole as jest.Mock).mockRejectedValue( + (UserRoleUseCase.prototype.createUserRole as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).post("/v1/users/user-123/roles").send({ roleId: 2 }); + const response = await supertest(app) + .post("/v1/users/user-123/roles") + .send({ roleId: 2 }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); @@ -192,10 +226,16 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { describe("DELETE /v1/users/:userId/roles/:roleId", () => { it("should return 200 on success", async () => { - const expectedResponse = new ResponseModel("deleteUserRole").withResponse(null); - (UserRoleUseCase.prototype.deleteUserRole as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("deleteUserRole").withResponse( + null, + ); + (UserRoleUseCase.prototype.deleteUserRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).delete("/v1/users/user-123/roles/2"); + const response = await supertest(app).delete( + "/v1/users/user-123/roles/2", + ); expect(response.status).toBe(HttpStatusCodes.OK); expect(UserRoleUseCase.prototype.deleteUserRole).toHaveBeenCalledTimes(1); @@ -213,7 +253,9 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { }); it("should return 400 when roleId is invalid", async () => { - const response = await supertest(app).delete("/v1/users/user-123/roles/invalid-id"); + const response = await supertest(app).delete( + "/v1/users/user-123/roles/invalid-id", + ); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); @@ -223,19 +265,25 @@ describe("UserRolesV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (UserRoleUseCase.prototype.deleteUserRole as jest.Mock).mockResolvedValue(expectedResponse); + (UserRoleUseCase.prototype.deleteUserRole as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).delete("/v1/users/user-123/roles/2"); + const response = await supertest(app).delete( + "/v1/users/user-123/roles/2", + ); expect(response.status).toBe(HttpStatusCodes.NOT_FOUND); }); it("should return 500 when delete throws an exception", async () => { - (UserRoleUseCase.prototype.deleteUserRole as jest.Mock).mockRejectedValue( + (UserRoleUseCase.prototype.deleteUserRole as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).delete("/v1/users/user-123/roles/2"); + const response = await supertest(app).delete( + "/v1/users/user-123/roles/2", + ); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); diff --git a/src/EntryPoints/UserRolesV1Router.ts b/src/EntryPoints/UserRolesV1Router.ts index 964f1db..1fa1999 100644 --- a/src/EntryPoints/UserRolesV1Router.ts +++ b/src/EntryPoints/UserRolesV1Router.ts @@ -1,18 +1,20 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { UserRole } from "@src/Domain/User/Entity/UserRole"; -import { UserRoleFilter } from "@src/Domain/User/Entity/UserRoleFilter"; -import { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { UserRole } from "@src/Domain/User/Entity/UserRole.js"; +import { UserRoleFilter } from "@src/Domain/User/Entity/UserRoleFilter.js"; +import type { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const USER_ROLES_V1_ROUTE = "/:userId/roles"; -export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router { +export function createUserRolesRouter( + userRoleUseCase: UserRoleUseCase, +): Router { const router = Router({ mergeParams: true }); router.get( @@ -21,7 +23,8 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router async (req: Request<{ userId: string }>, res) => { const transactionId = "queryUserRoles"; const { pageNumber, pageSize } = req.query; - const userId = req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; + const userId = + req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; try { if (!userId) { return res @@ -63,7 +66,8 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router async (req: Request<{ userId: string }>, res) => { const transactionId = "queryUserRolesDetails"; const { pageNumber, pageSize } = req.query; - const userId = req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; + const userId = + req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; try { if (!userId) { return res @@ -104,7 +108,8 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router hasPermissions(["users::update"]), async (req: Request<{ userId: string }>, res) => { const transactionId = "createUserRole"; - const userId = req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; + const userId = + req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; const { roleId } = req.body as { roleId?: string }; try { if (!userId || !roleId || Number.isNaN(Number(roleId))) { @@ -118,7 +123,10 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router ); } - const userRole: UserRole = new UserRole(userId, Number.parseInt(roleId)); + const userRole: UserRole = new UserRole( + userId, + Number.parseInt(roleId), + ); const request = new RequestModel(transactionId, userRole); const response = await userRoleUseCase.createUserRole(request); @@ -145,7 +153,8 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router hasPermissions(["users::update"]), async (req: Request<{ userId: string; roleId: string }>, res) => { const transactionId = "deleteUserRole"; - const userId = req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; + const userId = + req.headers["x-test-no-user-id"] === "true" ? "" : req.params.userId; const { roleId } = req.params; try { if (!userId || !roleId || Number.isNaN(Number(roleId))) { @@ -159,7 +168,10 @@ export function createUserRolesRouter(userRoleUseCase: UserRoleUseCase): Router ); } - const userRole: UserRole = new UserRole(userId, Number.parseInt(roleId)); + const userRole: UserRole = new UserRole( + userId, + Number.parseInt(roleId), + ); const request = new RequestModel(transactionId, userRole); const response = await userRoleUseCase.deleteUserRole(request); diff --git a/src/EntryPoints/UsersV1Router.test.ts b/src/EntryPoints/UsersV1Router.test.ts index 27bf70f..56a7271 100644 --- a/src/EntryPoints/UsersV1Router.test.ts +++ b/src/EntryPoints/UsersV1Router.test.ts @@ -1,38 +1,48 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import express, { Request, Response, NextFunction } from "express"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { User } from "@src/Domain/User/Entity/User.js"; +import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; +import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import express, { + type Request, + type Response, + type NextFunction, +} from "express"; import supertest from "supertest"; -import { createUsersRouter } from "./UsersV1Router"; -import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase"; -import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { User } from "@src/Domain/User/Entity/User"; +import { createUsersRouter } from "./UsersV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; -jest.mock("@src/Domain/User/UseCase/UserQueryUseCase"); -jest.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); -jest.mock("@src/Domain/User/UseCase/UserManagementUseCase"); +vi.mock("@src/Domain/User/UseCase/UserQueryUseCase"); +vi.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); +vi.mock("@src/Domain/User/UseCase/UserManagementUseCase"); interface CustomRequest { user?: { id: string }; } -const mockHasPermissions = jest.fn().mockImplementation((_permissions: string[]) => { - return (req: Request & CustomRequest, _res: Response, next: NextFunction) => { - req.user = { - id: "admin-id", - name: "Admin User", - email: "admin@example.com", - user: "admin", +const mockHasPermissions = vi + .fn() + .mockImplementation((_permissions: string[]) => { + return ( + req: Request & CustomRequest, + _res: Response, + next: NextFunction, + ) => { + req.user = { + id: "admin-id", + name: "Admin User", + email: "admin@example.com", + user: "admin", + }; + next(); }; - next(); - }; -}); + }); // Mock the hasPermissions middleware from security -jest.mock("@variamosple/variamos-security", () => ({ +vi.mock("@variamosple/variamos-security", () => ({ hasPermissions: (permissions: string[]) => mockHasPermissions(permissions), })); @@ -42,9 +52,9 @@ interface TestApiResponse { recoveryUrl?: string; } -import { IUserRepository } from "@src/Domain/User/IUserRepository"; -import { IMailService } from "@src/Domain/Mail/IMailService"; -import { UserPasswordUseCaseConfig } from "@src/Domain/User/UseCase/UserPasswordUseCase"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; +import type { UserPasswordUseCaseConfig } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; describe("UsersV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -59,7 +69,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { mock(), mock(), ); - const mockUserManagementUseCase = new UserManagementUseCase(mock()); + const mockUserManagementUseCase = new UserManagementUseCase( + mock(), + ); const mockUserRolesRouter = express.Router(); app.use( "/v1/users", @@ -74,7 +86,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("Route Permissions", () => { @@ -93,16 +105,30 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { describe("GET /v1/users", () => { it("should return 200 and list of users on success", async () => { const mockUsers = [ - User.builder().setId("1").setName("User One").setEmail("one@example.com").build(), - User.builder().setId("2").setName("User Two").setEmail("two@example.com").build(), + User.builder() + .setId("1") + .setName("User One") + .setEmail("one@example.com") + .build(), + User.builder() + .setId("2") + .setName("User Two") + .setEmail("two@example.com") + .build(), ]; - const expectedResponse = new ResponseModel("queryUsers", undefined, "Success").withResponse( - mockUsers, - ); + const expectedResponse = new ResponseModel( + "queryUsers", + undefined, + "Success", + ).withResponse(mockUsers); - (UserQueryUseCase.prototype.queryList as jest.Mock).mockResolvedValue(expectedResponse); + (UserQueryUseCase.prototype.queryList as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).get("/v1/users").query({ pageNumber: 1, pageSize: 10 }); + const response = await supertest(app) + .get("/v1/users") + .query({ pageNumber: 1, pageSize: 10 }); const body = response.body as TestApiResponse; expect(response.status).toBe(HttpStatusCodes.OK); @@ -118,7 +144,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "Invalid query", ); - (UserQueryUseCase.prototype.queryList as jest.Mock).mockResolvedValue(expectedResponse); + (UserQueryUseCase.prototype.queryList as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/users"); @@ -129,7 +157,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when query fails with database exception", async () => { - (UserQueryUseCase.prototype.queryList as jest.Mock).mockRejectedValue( + (UserQueryUseCase.prototype.queryList as vi.Mock).mockRejectedValue( new Error("Database Error"), ); @@ -151,7 +179,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { "Success", ).withResponse(mockUser); - (UserQueryUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); + (UserQueryUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/users/123"); @@ -168,7 +198,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "Not found", ); - (UserQueryUseCase.prototype.queryById as jest.Mock).mockResolvedValue(expectedResponse); + (UserQueryUseCase.prototype.queryById as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).get("/v1/users/123"); @@ -179,7 +211,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when queryById throws exception", async () => { - (UserQueryUseCase.prototype.queryById as jest.Mock).mockRejectedValue( + (UserQueryUseCase.prototype.queryById as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -198,9 +230,13 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { "generateRecoveryLink", undefined, "Success", - ).withResponse({ recoveryUrl: "http://localhost:3000/#/reset-password?token=some-token" }); + ).withResponse({ + recoveryUrl: "http://localhost:3000/#/reset-password?token=some-token", + }); - (UserPasswordUseCase.prototype.generateLink as jest.Mock).mockResolvedValue(expectedResponse); + (UserPasswordUseCase.prototype.generateLink as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).post("/v1/users/123/recovery-link"); @@ -209,15 +245,18 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { expect(UserPasswordUseCase.prototype.generateLink).toHaveBeenCalledWith( expect.objectContaining({ transactionId: "generateRecoveryLink" }), ); - expect(body.data.recoveryUrl).toContain("reset-password?token=some-token"); + expect(body.data.recoveryUrl).toContain( + "reset-password?token=some-token", + ); }); it("should return error status code when generateRecoveryLink fails", async () => { - const expectedResponse = new ResponseModel("generateRecoveryLink").withError( - DomainErrorCodes.ENTITY_NOT_FOUND, - "User not found", + const expectedResponse = new ResponseModel( + "generateRecoveryLink", + ).withError(DomainErrorCodes.ENTITY_NOT_FOUND, "User not found"); + (UserPasswordUseCase.prototype.generateLink as vi.Mock).mockResolvedValue( + expectedResponse, ); - (UserPasswordUseCase.prototype.generateLink as jest.Mock).mockResolvedValue(expectedResponse); const response = await supertest(app).post("/v1/users/123/recovery-link"); @@ -228,7 +267,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when generateRecoveryLink throws exception", async () => { - (UserPasswordUseCase.prototype.generateLink as jest.Mock).mockRejectedValue( + (UserPasswordUseCase.prototype.generateLink as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -249,7 +288,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { "User disabled", ).withResponse(null); - (UserManagementUseCase.prototype.disable as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.disable as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).put("/v1/users/123/disable"); @@ -264,7 +305,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "User not found", ); - (UserManagementUseCase.prototype.disable as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.disable as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).put("/v1/users/123/disable"); @@ -275,7 +318,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when disableUser throws exception", async () => { - (UserManagementUseCase.prototype.disable as jest.Mock).mockRejectedValue( + (UserManagementUseCase.prototype.disable as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -296,7 +339,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { "User enabled", ).withResponse(null); - (UserManagementUseCase.prototype.enable as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.enable as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).put("/v1/users/123/enable"); @@ -311,7 +356,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "User not found", ); - (UserManagementUseCase.prototype.enable as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.enable as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).put("/v1/users/123/enable"); @@ -322,7 +369,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when enableUser throws exception", async () => { - (UserManagementUseCase.prototype.enable as jest.Mock).mockRejectedValue( + (UserManagementUseCase.prototype.enable as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); @@ -343,7 +390,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { "User deleted", ).withResponse(null); - (UserManagementUseCase.prototype.delete as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.delete as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).delete("/v1/users/123"); @@ -358,7 +407,9 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.ENTITY_NOT_FOUND, "User not found", ); - (UserManagementUseCase.prototype.delete as jest.Mock).mockResolvedValue(expectedResponse); + (UserManagementUseCase.prototype.delete as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app).delete("/v1/users/123"); @@ -369,7 +420,7 @@ describe("UsersV1Router Integration Tests - Extended Coverage", () => { }); it("should return 500 when deleteUser throws exception", async () => { - (UserManagementUseCase.prototype.delete as jest.Mock).mockRejectedValue( + (UserManagementUseCase.prototype.delete as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); diff --git a/src/EntryPoints/UsersV1Router.ts b/src/EntryPoints/UsersV1Router.ts index 6c78590..e9db7b4 100644 --- a/src/EntryPoints/UsersV1Router.ts +++ b/src/EntryPoints/UsersV1Router.ts @@ -1,15 +1,15 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { UserFilter } from "@src/Domain/User/Entity/UserFilter"; -import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase"; -import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { UserFilter } from "@src/Domain/User/Entity/UserFilter.js"; +import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; +import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; import { hasPermissions } from "@variamosple/variamos-security"; -import { Router, Request } from "express"; +import { type Request, Router } from "express"; import logger from "jet-logger"; -import { USER_ROLES_V1_ROUTE } from "./UserRolesV1Router"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; +import { USER_ROLES_V1_ROUTE } from "./UserRolesV1Router.js"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const USERS_V1_ROUTE = "/v1/users"; @@ -35,7 +35,9 @@ export function createUsersRouter( const request = new RequestModel(transactionId, filter); const response = await userQueryUseCase.queryList(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); @@ -59,7 +61,9 @@ export function createUsersRouter( const request = new RequestModel(transactionId, userId); const response = await userQueryUseCase.queryById(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); @@ -82,13 +86,18 @@ export function createUsersRouter( const adminId = (req.user as { id: string }).id; try { - const request = new RequestModel<{ userId: string; adminId: string }>(transactionId, { - userId, - adminId, - }); + const request = new RequestModel<{ userId: string; adminId: string }>( + transactionId, + { + userId, + adminId, + }, + ); const response = await userPasswordUseCase.generateLink(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); @@ -113,7 +122,9 @@ export function createUsersRouter( const request = new RequestModel(transactionId, userId); const response = await userManagementUseCase.disable(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); @@ -138,7 +149,9 @@ export function createUsersRouter( const request = new RequestModel(transactionId, userId); const response = await userManagementUseCase.enable(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); @@ -163,7 +176,9 @@ export function createUsersRouter( const request = new RequestModel(transactionId, userId); const response = await userManagementUseCase.delete(request); - const status = mapDomainErrorToHttpStatus(response.errorCode as DomainErrorCodes); + const status = mapDomainErrorToHttpStatus( + response.errorCode as DomainErrorCodes, + ); res.status(status).json(response); } catch (error) { logger.err(error as Error); diff --git a/src/EntryPoints/VisitsV1Router.test.ts b/src/EntryPoints/VisitsV1Router.test.ts index 9bfba11..74c6c94 100644 --- a/src/EntryPoints/VisitsV1Router.test.ts +++ b/src/EntryPoints/VisitsV1Router.test.ts @@ -1,29 +1,33 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; +import { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createVisitsRouter } from "./VisitsV1Router"; -import { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { Visit } from "@src/Domain/Visit/Entity/Visit"; +import { createVisitsRouter } from "./VisitsV1Router.js"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; interface CustomRequest { user?: { id: string }; } // Mock dependencies -jest.mock("@src/Domain/Visit/UseCase/VisitUseCase"); -jest.mock("@variamosple/variamos-security", () => ({ - isAuthenticated: (req: express.Request, _res: express.Response, next: () => void) => { +vi.mock("@src/Domain/Visit/UseCase/VisitUseCase"); +vi.mock("@variamosple/variamos-security", () => ({ + isAuthenticated: ( + req: express.Request, + _res: express.Response, + next: () => void, + ) => { (req as CustomRequest).user = { id: "user-123" }; next(); }, })); -import { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository"; -import { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository"; +import type { ICountriesRepository } from "@src/Domain/Countries/Repository/ICountriesRepository.js"; +import type { IVisitRepository } from "@src/Domain/Visit/Repository/IVisitRepository.js"; describe("VisitsV1Router Integration Tests - Extended Coverage", () => { let app: express.Application; @@ -39,14 +43,18 @@ describe("VisitsV1Router Integration Tests - Extended Coverage", () => { }); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe("POST /v1/visits", () => { it("should return 200 on success when using x-forwarded-for header", async () => { const mockVisit = new Visit("home-page", "user-123"); - const expectedResponse = new ResponseModel("createVisit").withResponse(mockVisit); - (VisitUseCase.prototype.registerVisit as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("createVisit").withResponse( + mockVisit, + ); + (VisitUseCase.prototype.registerVisit as vi.Mock).mockResolvedValue( + expectedResponse, + ); const response = await supertest(app) .post("/v1/visits") @@ -62,10 +70,16 @@ describe("VisitsV1Router Integration Tests - Extended Coverage", () => { it("should return 200 on success when using fallback client ip", async () => { const mockVisit = new Visit("home-page", "user-123"); - const expectedResponse = new ResponseModel("createVisit").withResponse(mockVisit); - (VisitUseCase.prototype.registerVisit as jest.Mock).mockResolvedValue(expectedResponse); + const expectedResponse = new ResponseModel("createVisit").withResponse( + mockVisit, + ); + (VisitUseCase.prototype.registerVisit as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/visits").send({ pageId: "home-page" }); + const response = await supertest(app) + .post("/v1/visits") + .send({ pageId: "home-page" }); expect(response.status).toBe(HttpStatusCodes.OK); expect(VisitUseCase.prototype.registerVisit).toHaveBeenCalledWith( @@ -85,19 +99,25 @@ describe("VisitsV1Router Integration Tests - Extended Coverage", () => { DomainErrorCodes.INVALID_INPUT, "register failed", ); - (VisitUseCase.prototype.registerVisit as jest.Mock).mockResolvedValue(expectedResponse); + (VisitUseCase.prototype.registerVisit as vi.Mock).mockResolvedValue( + expectedResponse, + ); - const response = await supertest(app).post("/v1/visits").send({ pageId: "home-page" }); + const response = await supertest(app) + .post("/v1/visits") + .send({ pageId: "home-page" }); expect(response.status).toBe(HttpStatusCodes.BAD_REQUEST); }); it("should return 500 when register throws an exception", async () => { - (VisitUseCase.prototype.registerVisit as jest.Mock).mockRejectedValue( + (VisitUseCase.prototype.registerVisit as vi.Mock).mockRejectedValue( new Error("Unexpected error"), ); - const response = await supertest(app).post("/v1/visits").send({ pageId: "home-page" }); + const response = await supertest(app) + .post("/v1/visits") + .send({ pageId: "home-page" }); expect(response.status).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); diff --git a/src/EntryPoints/VisitsV1Router.ts b/src/EntryPoints/VisitsV1Router.ts index 15a454e..fdbbb78 100644 --- a/src/EntryPoints/VisitsV1Router.ts +++ b/src/EntryPoints/VisitsV1Router.ts @@ -1,13 +1,13 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RequestModel } from "@src/Domain/Core/Entity/RequestModel"; -import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel"; -import { Visit } from "@src/Domain/Visit/Entity/Visit"; -import { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase"; +import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; +import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; +import type { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { isAuthenticated } from "@variamosple/variamos-security"; import { Router } from "express"; import logger from "jet-logger"; -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; export const VISITS_V1_ROUTE = "/v1/visits"; @@ -18,7 +18,8 @@ export function createVisitsRouter(visitUseCase: VisitUseCase): Router { const transactionId = "createVisit"; const user = req.user; const { pageId } = req.body as { pageId?: string }; - const ipAddress: string | undefined = (req.headers["x-forwarded-for"] as string) || req.ip; + const ipAddress: string | undefined = + (req.headers["x-forwarded-for"] as string) || req.ip; try { if (!pageId || !user || !user.id) { diff --git a/src/EntryPoints/errorMapper.test.ts b/src/EntryPoints/errorMapper.test.ts index dc87373..1872904 100644 --- a/src/EntryPoints/errorMapper.test.ts +++ b/src/EntryPoints/errorMapper.test.ts @@ -1,6 +1,6 @@ -import { mapDomainErrorToHttpStatus } from "./errorMapper"; -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; describe("errorMapper Unit Tests", () => { it("should return OK if no error code is provided", () => { @@ -15,9 +15,9 @@ describe("errorMapper Unit Tests", () => { expect(mapDomainErrorToHttpStatus(DomainErrorCodes.ENTITY_NOT_FOUND)).toBe( HttpStatusCodes.NOT_FOUND, ); - expect(mapDomainErrorToHttpStatus(DomainErrorCodes.UNAUTHORIZED_ACCESS)).toBe( - HttpStatusCodes.UNAUTHORIZED, - ); + expect( + mapDomainErrorToHttpStatus(DomainErrorCodes.UNAUTHORIZED_ACCESS), + ).toBe(HttpStatusCodes.UNAUTHORIZED); expect(mapDomainErrorToHttpStatus(DomainErrorCodes.SYSTEM_ERROR)).toBe( HttpStatusCodes.INTERNAL_SERVER_ERROR, ); @@ -28,9 +28,9 @@ describe("errorMapper Unit Tests", () => { }); it("should return INTERNAL_SERVER_ERROR if it is an unknown domain error code and not a number", () => { - expect(mapDomainErrorToHttpStatus("UNKNOWN_ERROR" as DomainErrorCodes)).toBe( - HttpStatusCodes.INTERNAL_SERVER_ERROR, - ); + expect( + mapDomainErrorToHttpStatus("UNKNOWN_ERROR" as DomainErrorCodes), + ).toBe(HttpStatusCodes.INTERNAL_SERVER_ERROR); }); it("should return parsed number if errorCode is a numeric string", () => { diff --git a/src/EntryPoints/errorMapper.ts b/src/EntryPoints/errorMapper.ts index 45ba692..0ab16c5 100644 --- a/src/EntryPoints/errorMapper.ts +++ b/src/EntryPoints/errorMapper.ts @@ -1,5 +1,5 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; export function mapDomainErrorToHttpStatus( errorCode?: string | number | null, @@ -20,7 +20,7 @@ export function mapDomainErrorToHttpStatus( default: { if (typeof errorCode === "number") return errorCode; const parsed = Number(errorCode); - if (!isNaN(parsed)) return parsed; + if (!Number.isNaN(parsed)) return parsed; return HttpStatusCodes.INTERNAL_SERVER_ERROR; } } diff --git a/src/EntryPoints/index.ts b/src/EntryPoints/index.ts index b995921..96b133f 100644 --- a/src/EntryPoints/index.ts +++ b/src/EntryPoints/index.ts @@ -1,44 +1,60 @@ -import EnvVars from "@src/common/EnvVars"; +import EnvVars from "@src/common/EnvVars.js"; import { Router } from "express"; -import { createAuthRouter, AUTH_ROUTE } from "./AuthRouter"; -import { createConfigurationRouter, CONFIGURATION_V1_ROUTE } from "./ConfigurationRouter"; -import { createCountriesRouter, COUNTRIES_V1_ROUTE } from "./CountriesV1Router"; -import { createMetricsRouter, METRICS_V1_ROUTE } from "./MetricsV1Router"; -import { createMicroServicesRouter, MICRO_SERVICES_V1_ROUTE } from "./MicroServicesV1Router"; -import { createPermissionsRouter, PERMISSIONS_V1_ROUTE } from "./PermissionsV1Router"; -import { createRolesRouter, ROLES_V1_ROUTE } from "./RolesV1Router"; -import { createRolePermissionsRouter } from "./RolePermissionsV1Router"; -import { createUsersRouter, USERS_V1_ROUTE } from "./UsersV1Router"; -import { createUserRolesRouter } from "./UserRolesV1Router"; -import { createVisitsRouter, VISITS_V1_ROUTE } from "./VisitsV1Router"; -import { createBugRouter, BUG_V1_ROUTE, MulterUpload } from "./BugRouter"; +import { AUTH_ROUTE, createAuthRouter } from "./AuthRouter.js"; +import { + BUG_V1_ROUTE, + type MulterUpload, + createBugRouter, +} from "./BugRouter.js"; +import { + CONFIGURATION_V1_ROUTE, + createConfigurationRouter, +} from "./ConfigurationRouter.js"; +import { + COUNTRIES_V1_ROUTE, + createCountriesRouter, +} from "./CountriesV1Router.js"; +import { METRICS_V1_ROUTE, createMetricsRouter } from "./MetricsV1Router.js"; +import { + MICRO_SERVICES_V1_ROUTE, + createMicroServicesRouter, +} from "./MicroServicesV1Router.js"; +import { + PERMISSIONS_V1_ROUTE, + createPermissionsRouter, +} from "./PermissionsV1Router.js"; +import { createRolePermissionsRouter } from "./RolePermissionsV1Router.js"; +import { ROLES_V1_ROUTE, createRolesRouter } from "./RolesV1Router.js"; +import { createUserRolesRouter } from "./UserRolesV1Router.js"; +import { USERS_V1_ROUTE, createUsersRouter } from "./UsersV1Router.js"; +import { VISITS_V1_ROUTE, createVisitsRouter } from "./VisitsV1Router.js"; // User Flow Use Cases -import { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase"; -import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase"; -import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase"; -import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase"; -import { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase"; +import type { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; +import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; +import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; +import type { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; +import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; +import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; +import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js"; // Bug Flow Use Cases -import { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase"; -import { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase"; -import { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase"; -import { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase"; -import { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase"; +import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; +import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; +import type { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; // Role & Permission Use Cases -import { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase"; -import { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase"; -import { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase"; -import { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase"; +import type { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; +import type { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; +import type { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; +import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; // Other Use Cases -import { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase"; -import { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase"; -import { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase"; -import { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"; -import { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase"; +import type { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; +import type { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; +import type { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +import type { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; import { isAuthenticated } from "@variamosple/variamos-security"; @@ -96,7 +112,9 @@ export function createBaseRouter( usersUseCases.management, userRolesRouter, ); - const rolePermissionsRouter = createRolePermissionsRouter(rolesUseCases.permission); + const rolePermissionsRouter = createRolePermissionsRouter( + rolesUseCases.permission, + ); const rolesV1Router = createRolesRouter( rolesUseCases.management, rolesUseCases.query, @@ -131,7 +149,7 @@ export function createBaseRouter( baseRouter.use(COUNTRIES_V1_ROUTE, countriesV1Router); baseRouter.use(BUG_V1_ROUTE, bugV1Router); - baseRouter.get("/version", function (_, res) { + baseRouter.get("/version", (_, res) => { try { const data = { message: "variamos_ms_admin", diff --git a/src/Infrastructure/GitHub/GitHubIssuesService.ts b/src/Infrastructure/GitHub/GitHubIssuesService.ts index 4792d31..54ee7f7 100644 --- a/src/Infrastructure/GitHub/GitHubIssuesService.ts +++ b/src/Infrastructure/GitHub/GitHubIssuesService.ts @@ -1,5 +1,8 @@ +import type { + GitHubIssue, + IIssueTrackerService, +} from "@src/Domain/Core/Service/IIssueTrackerService.js"; import axios from "axios"; -import { IIssueTrackerService, GitHubIssue } from "@src/Domain/Core/Service/IIssueTrackerService"; import logger from "jet-logger"; interface GitHubError { @@ -79,11 +82,19 @@ export class GitHubIssuesService implements IIssueTrackerService { } } - public async closeIssue(repo: string, issueNumber: number, token: string): Promise { + public async closeIssue( + repo: string, + issueNumber: number, + token: string, + ): Promise { const url = `https://api.github.com/repos/${repo}/issues/${issueNumber}`; try { - await axios.patch(url, { state: "closed" }, { headers: this.getHeaders(token) }); + await axios.patch( + url, + { state: "closed" }, + { headers: this.getHeaders(token) }, + ); return true; } catch (error) { const err = error as GitHubError; @@ -93,11 +104,19 @@ export class GitHubIssuesService implements IIssueTrackerService { } } - public async reopenIssue(repo: string, issueNumber: number, token: string): Promise { + public async reopenIssue( + repo: string, + issueNumber: number, + token: string, + ): Promise { const url = `https://api.github.com/repos/${repo}/issues/${issueNumber}`; try { - await axios.patch(url, { state: "open" }, { headers: this.getHeaders(token) }); + await axios.patch( + url, + { state: "open" }, + { headers: this.getHeaders(token) }, + ); return true; } catch (error) { const err = error as GitHubError; @@ -107,7 +126,10 @@ export class GitHubIssuesService implements IIssueTrackerService { } } - public async getIssues(repo: string, token: string): Promise { + public async getIssues( + repo: string, + token: string, + ): Promise { const url = `https://api.github.com/repos/${repo}/issues?state=all&per_page=100`; try { diff --git a/src/Infrastructure/Mail/MailService.ts b/src/Infrastructure/Mail/MailService.ts index 636f452..7f21f2e 100644 --- a/src/Infrastructure/Mail/MailService.ts +++ b/src/Infrastructure/Mail/MailService.ts @@ -1,8 +1,8 @@ +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import EnvVars from "@src/common/EnvVars.js"; +import logger from "jet-logger"; /* cspell:disable */ import nodemailer from "nodemailer"; -import logger from "jet-logger"; -import EnvVars from "@src/common/EnvVars"; -import { IMailService } from "@src/Domain/Mail/IMailService"; export class MailServiceImpl implements IMailService { private transporter = nodemailer.createTransport({ @@ -21,10 +21,17 @@ export class MailServiceImpl implements IMailService { /** * Sends an email in text or HTML format */ - public async sendMail(to: string, subject: string, html: string): Promise { + public async sendMail( + to: string, + subject: string, + html: string, + ): Promise { try { // If in development/testing mode and no SMTP credentials are provided, simulate the email sending - if (EnvVars.NodeEnv !== "production" && (!EnvVars.SMTP.USER || !EnvVars.SMTP.PASSWORD)) { + if ( + EnvVars.NodeEnv !== "production" && + (!EnvVars.SMTP.USER || !EnvVars.SMTP.PASSWORD) + ) { logger.info(`[MAIL DEV ONLY] Simulate sending email to ${to}: Subject: ${subject} Content: ${html}`); @@ -38,7 +45,9 @@ export class MailServiceImpl implements IMailService { html, }); - logger.info(`[MAIL] Email sent successfully to ${to}. MessageId: ${info.messageId}`); + logger.info( + `[MAIL] Email sent successfully to ${to}. MessageId: ${info.messageId}`, + ); return true; } catch (error) { const err = error as Error; @@ -50,9 +59,13 @@ export class MailServiceImpl implements IMailService { /** * Sends a password reset email containing the recovery link */ - public async sendPasswordResetMail(to: string, recoveryLink: string): Promise { + public async sendPasswordResetMail( + to: string, + recoveryLink: string, + ): Promise { const subject = "VariaMos - Password Recovery Request"; - const logoUrl = "https://app.variamos.com/variamos_admin/images/VariaMosLogo.png"; + const logoUrl = + "https://app.variamos.com/variamos_admin/images/VariaMosLogo.png"; const html = `
diff --git a/src/Infrastructure/Storage/DiskStorageService.ts b/src/Infrastructure/Storage/DiskStorageService.ts index 6ab534e..eeba3cb 100644 --- a/src/Infrastructure/Storage/DiskStorageService.ts +++ b/src/Infrastructure/Storage/DiskStorageService.ts @@ -1,7 +1,7 @@ -import { IStorageService } from "@src/Domain/Core/Service/IStorageService"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import type { IStorageService } from "@src/Domain/Core/Service/IStorageService.js"; import logger from "jet-logger"; -import * as fs from "fs"; -import * as path from "path"; export class DiskStorageService implements IStorageService { public async deleteFile(filePath: string): Promise { @@ -10,7 +10,9 @@ export class DiskStorageService implements IStorageService { return new Promise((resolve) => { fs.unlink(absolutePath, (err) => { if (err) { - logger.err(`Failed to delete physical file: ${absolutePath}. ${err.message}`); + logger.err( + `Failed to delete physical file: ${absolutePath}. ${err.message}`, + ); } else { logger.info(`Successfully deleted physical file: ${absolutePath}`); } diff --git a/src/Infrastructure/VariamosORM.ts b/src/Infrastructure/VariamosORM.ts index ec3ca4f..10b91ac 100644 --- a/src/Infrastructure/VariamosORM.ts +++ b/src/Infrastructure/VariamosORM.ts @@ -1,22 +1,27 @@ -import EnvVars from "@src/common/EnvVars"; +import EnvVars from "@src/common/EnvVars.js"; import { Sequelize } from "sequelize"; -const VARIAMOS_ORM = new Sequelize(EnvVars.DB.DATABASE, EnvVars.DB.USER, EnvVars.DB.PASSWORD, { - host: EnvVars.DB.HOST, - dialect: "postgres", - pool: { - max: 5, - min: 0, - idle: 10000, +const VARIAMOS_ORM = new Sequelize( + EnvVars.DB.DATABASE, + EnvVars.DB.USER, + EnvVars.DB.PASSWORD, + { + host: EnvVars.DB.HOST, + dialect: "postgres", + pool: { + max: 5, + min: 0, + idle: 10000, + }, + dialectOptions: { + ssl: EnvVars.DB.SSL, + }, + define: { + charset: "utf8", + collate: "utf8_general_ci", + timestamps: true, + }, }, - dialectOptions: { - ssl: EnvVars.DB.SSL, - }, - define: { - charset: "utf8", - collate: "utf8_general_ci", - timestamps: true, - }, -}); +); export const DB_SCHEMA = EnvVars.DB.SCHEMA; export default VARIAMOS_ORM; diff --git a/src/common/HttpStatusCodes.ts b/src/common/HttpStatusCodes.ts index 1795f0c..01f3e28 100644 --- a/src/common/HttpStatusCodes.ts +++ b/src/common/HttpStatusCodes.ts @@ -1,5 +1,5 @@ /* cspell:disable */ -/* eslint-disable max-len */ + /** * This file was copied from here: https://gist.github.com/scokmen/f813c904ef79022e84ab2409574d1b45 */ diff --git a/src/common/classes.ts b/src/common/classes.ts index 0073258..227e489 100644 --- a/src/common/classes.ts +++ b/src/common/classes.ts @@ -1,4 +1,4 @@ -import HttpStatusCodes from "@src/common/HttpStatusCodes"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; /** * Error with status code and message. @@ -23,6 +23,6 @@ export class ValidationErr extends RouteError { } public static GetMsg(param: string) { - return ValidationErr.MSG + param + '".'; + return `${ValidationErr.MSG + param}".`; } } diff --git a/src/index.ts b/src/index.ts index ff4bc5b..25023d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,46 +1,46 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import logger from "jet-logger"; -import "./pre-start"; // Must be the first import +import "./pre-start.js"; // Must be the first import -import EnvVars from "@src/common/EnvVars"; +import type { Readable } from "node:stream"; +import EnvVars from "@src/common/EnvVars.js"; import { initKeyStore, validateSession } from "@variamosple/variamos-security"; -import * as cookie from "cookie"; -import { Readable } from "stream"; +import { parseCookie } from "cookie"; import { WebSocket, WebSocketServer } from "ws"; -import { RequestModel } from "./Domain/Core/Entity/RequestModel"; -import { createBaseRouter } from "./EntryPoints"; -import { createServer } from "./server"; +import { RequestModel } from "./Domain/Core/Entity/RequestModel.js"; +import { createBaseRouter } from "./EntryPoints/index.js"; +import { createServer } from "./server.js"; import { - productionUserAuthUseCase, - productionUserPasswordUseCase, - productionUserManagementUseCase, - productionUserQueryUseCase, - productionUserRoleUseCase, - productionBugSubmissionUseCase, + productionBugAttachmentUseCase, productionBugLifecycleUseCase, - productionBugSyncUseCase, productionBugQueryUseCase, - productionBugAttachmentUseCase, - productionMicroServiceQueryUseCase, + productionBugSubmissionUseCase, + productionBugSyncUseCase, + productionCountriesQueryUseCase, + productionMetricsQueryUseCase, productionMicroServiceManagementUseCase, + productionMicroServiceQueryUseCase, + productionPermissionUseCase, productionRoleManagementUseCase, - productionRoleQueryUseCase, productionRolePermissionUseCase, - productionMetricsQueryUseCase, - productionPermissionUseCase, + productionRoleQueryUseCase, + productionUserAuthUseCase, + productionUserManagementUseCase, + productionUserPasswordUseCase, + productionUserQueryUseCase, + productionUserRoleUseCase, productionVisitUseCase, - productionCountriesQueryUseCase, -} from "./CompositionRoot"; +} from "./CompositionRoot.js"; -import { BugModel } from "./DataProviders/Bug/Bug"; -import { BugAttachmentModel } from "./DataProviders/Bug/BugAttachment"; -import { BugLogModel } from "./DataProviders/Bug/BugLog"; -import "./DataProviders/Bug/BugAssociations"; +import { BugModel } from "./DataProviders/Bug/Bug.js"; +import { BugAttachmentModel } from "./DataProviders/Bug/BugAttachment.js"; +import { BugLogModel } from "./DataProviders/Bug/BugLog.js"; +import "./DataProviders/Bug/BugAssociations.js"; +import fs from "node:fs"; +import path from "node:path"; import multer from "multer"; -import path from "path"; -import fs from "fs"; // Ensure uploads directory exists const uploadsDir = path.join(__dirname, "./public/uploads"); @@ -54,7 +54,7 @@ const storage = multer.diskStorage({ cb(null, uploadsDir); }, filename: (_req, file, cb) => { - const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); + const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1e9)}`; cb(null, uniqueSuffix + path.extname(file.originalname)); }, }); @@ -93,7 +93,7 @@ const baseRouter = createBaseRouter( const app = createServer(baseRouter); -const SERVER_START_MSG = "Express server started on port: " + EnvVars.Port.toString(); +const SERVER_START_MSG = `Express server started on port: ${EnvVars.Port.toString()}`; const server = app.listen(EnvVars.Port, async () => { initKeyStore().then(); @@ -111,7 +111,7 @@ const server = app.listen(EnvVars.Port, async () => { await productionBugLifecycleUseCase.purgeExpiredRejectedBugs(); } catch (e) { const err = e as Error; - logger.err("Failed to synchronize Bug tracker models: " + err.message); + logger.err(`Failed to synchronize Bug tracker models: ${err.message}`); } // Run periodic bugs sync every 15 minutes @@ -123,7 +123,7 @@ const server = app.listen(EnvVars.Port, async () => { await productionBugSyncUseCase.syncBugs(request); } catch (e) { const err = e as Error; - logger.err("Failed to execute periodic bugs sync: " + err.message); + logger.err(`Failed to execute periodic bugs sync: ${err.message}`); } }, SYNC_INTERVAL); @@ -135,7 +135,9 @@ const server = app.listen(EnvVars.Port, async () => { await productionBugLifecycleUseCase.purgeExpiredRejectedBugs(); } catch (e) { const err = e as Error; - logger.err("Failed to execute periodic expired bugs purge: " + err.message); + logger.err( + `Failed to execute periodic expired bugs purge: ${err.message}`, + ); } }, PURGE_INTERVAL); }); @@ -145,7 +147,7 @@ const webSocketServer = new WebSocketServer({ server }); webSocketServer.on("connection", async (ws, req) => { logger.info("WebSocket connection established"); - const cookies = req.headers.cookie ? cookie.parse(req.headers.cookie) : {}; + const cookies = req.headers.cookie ? parseCookie(req.headers.cookie) : {}; const validationResponse = await validateSession(cookies.authToken); @@ -155,17 +157,23 @@ webSocketServer.on("connection", async (ws, req) => { } ws.on("message", async (message) => { - const messageStr = Buffer.isBuffer(message) ? message.toString("utf8") : String(message); - logger.info("Message received: " + messageStr); + const messageStr = Buffer.isBuffer(message) + ? message.toString("utf8") + : String(message); + logger.info(`Message received: ${messageStr}`); try { const parsedData = JSON.parse(messageStr) as { microserviceId?: string }; const microserviceId = parsedData.microserviceId; const transactionId = "watchMicroServiceLogs"; - const request = new RequestModel(transactionId, microserviceId as string); + const request = new RequestModel( + transactionId, + microserviceId as string, + ); - const response = await productionMicroServiceQueryUseCase.watchMicroServiceLogs(request); + const response = + await productionMicroServiceQueryUseCase.watchMicroServiceLogs(request); if (response.errorCode) { return ws.send(JSON.stringify(response)); @@ -176,7 +184,7 @@ webSocketServer.on("connection", async (ws, req) => { JSON.stringify( response.withError( DomainErrorCodes.ENTITY_NOT_FOUND, - "No Logs found for microservice with id: " + microserviceId, + `No Logs found for microservice with id: ${microserviceId}`, ), ), ); diff --git a/src/pre-start.ts b/src/pre-start.ts index 646d911..0558145 100644 --- a/src/pre-start.ts +++ b/src/pre-start.ts @@ -5,7 +5,7 @@ */ // NOTE: DO NOT IMPORT ANY SOURCE CODE HERE -import path from "path"; +import path from "node:path"; import dotenv from "dotenv"; import { parse } from "ts-command-line-args"; diff --git a/src/server.ts b/src/server.ts index 1ce3d03..d21a594 100644 --- a/src/server.ts +++ b/src/server.ts @@ -2,18 +2,23 @@ * Setup express server. */ +import path from "node:path"; import cookieParser from "cookie-parser"; import cors from "cors"; -import express, { NextFunction, Request, Response, Router } from "express"; +import express, { + type NextFunction, + type Request, + type Response, + type Router, +} from "express"; import helmet from "helmet"; import logger from "jet-logger"; import morgan from "morgan"; -import path from "path"; -import EnvVars from "@src/common/EnvVars"; -import HttpStatusCodes from "@src/common/HttpStatusCodes"; -import { RouteError } from "@src/common/classes"; -import { NodeEnvs } from "@src/common/misc"; +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { RouteError } from "@src/common/classes.js"; +import { NodeEnvs } from "@src/common/misc.js"; export function createServer(baseRouter: Router) { const app = express(); @@ -33,7 +38,9 @@ export function createServer(baseRouter: Router) { if (!origin || "null" === origin) return callback(null, true); const isAllowed = - EnvVars.CORS.AllowedOriginsPatterns.findIndex((pattern) => pattern.test(origin)) !== -1; + EnvVars.CORS.AllowedOriginsPatterns.findIndex((pattern) => + pattern.test(origin), + ) !== -1; if (isAllowed) { callback(null, true); @@ -66,7 +73,7 @@ export function createServer(baseRouter: Router) { _: Request, res: Response, // eslint-disable-next-line @typescript-eslint/no-unused-vars - next: NextFunction, + _next: NextFunction, ) => { if (EnvVars.NodeEnv !== NodeEnvs.Test.valueOf()) { logger.err(err, true); diff --git a/stryker.config.json b/stryker.config.json index 783ac19..70cd792 100644 --- a/stryker.config.json +++ b/stryker.config.json @@ -7,16 +7,11 @@ "!src/Domain/**/*.{test,spec}.ts", "!src/EntryPoints/**/*.{test,spec}.ts" ], - "testRunner": "jest", + "testRunner": "vitest", "checkers": ["typescript"], "tsconfigFile": "tsconfig.json", - "jest": { - "projectType": "custom", - "configFile": "jest.config.ts", - "config": { - "testMatch": ["**/src/**/*.spec.ts", "**/src/**/*.test.ts"], - "maxWorkers": 1 - } + "vitest": { + "configFile": "vitest.config.ts" }, "reporters": ["progress", "clear-text", "html"], "concurrency": 2, diff --git a/stryker.domain.config.json b/stryker.domain.config.json index 01d9329..2b21c17 100644 --- a/stryker.domain.config.json +++ b/stryker.domain.config.json @@ -5,16 +5,11 @@ "!src/Domain/**/Entity/*.ts", "!src/Domain/**/*.{test,spec}.ts" ], - "testRunner": "jest", + "testRunner": "vitest", "checkers": ["typescript"], "tsconfigFile": "tsconfig.json", - "jest": { - "projectType": "custom", - "configFile": "jest.config.ts", - "config": { - "testMatch": ["**/src/**/*.spec.ts", "**/src/**/*.test.ts"], - "maxWorkers": 1 - } + "vitest": { + "configFile": "vitest.config.ts" }, "reporters": ["progress", "clear-text", "html"], "concurrency": 2, diff --git a/stryker.entrypoints.config.json b/stryker.entrypoints.config.json index 0ccd643..d484ca1 100644 --- a/stryker.entrypoints.config.json +++ b/stryker.entrypoints.config.json @@ -4,16 +4,11 @@ "src/EntryPoints/**/*.ts", "!src/EntryPoints/**/*.{test,spec}.ts" ], - "testRunner": "jest", + "testRunner": "vitest", "checkers": ["typescript"], "tsconfigFile": "tsconfig.json", - "jest": { - "projectType": "custom", - "configFile": "jest.config.ts", - "config": { - "testMatch": ["**/src/**/*.spec.ts", "**/src/**/*.test.ts"], - "maxWorkers": 1 - } + "vitest": { + "configFile": "vitest.config.ts" }, "reporters": ["progress", "clear-text", "html"], "concurrency": 2, diff --git a/tsconfig.json b/tsconfig.json index d89dcd0..1106027 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "module": "node16", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ @@ -41,7 +41,7 @@ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "moduleResolution": "node16", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..27d4dd7 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,33 @@ +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; +import * as dotenv from "dotenv"; +import * as path from "path"; + +// Load test env variables +dotenv.config({ path: path.join(process.cwd(), "env/test.env") }); + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + globals: true, + environment: "node", + setupFiles: ["./vitest.setup.ts"], + coverage: { + provider: "v8", + include: ["src/Domain/**/*.ts", "src/EntryPoints/**/*.ts"], + exclude: [ + "src/EntryPoints/index.ts", + "src/Domain/Validations/ValidationMessages.ts", + "src/**/*.d.ts", + ], + thresholds: { + global: { + branches: 80, + functions: 80, + lines: 80, + statements: 80, + }, + }, + }, + }, +}); diff --git a/vitest.setup.ts b/vitest.setup.ts new file mode 100644 index 0000000..439861d --- /dev/null +++ b/vitest.setup.ts @@ -0,0 +1,31 @@ +import { vi, afterAll } from "vitest"; +import VARIAMOS_ORM from "./src/Infrastructure/VariamosORM.js"; + +// Set global jest object to map to Vitest's vi to support all existing test code without rewriting it +(globalThis as any).jest = vi; + +// Silence console logs and errors during test executions to keep output clean +vi.spyOn(console, "log").mockImplementation(() => {}); +vi.spyOn(console, "error").mockImplementation(() => {}); +vi.spyOn(console, "warn").mockImplementation(() => {}); + +// Mock jet-logger globally to prevent process.stdout writes during tests +vi.mock("jet-logger", () => ({ + info: vi.fn(), + warn: vi.fn(), + err: vi.fn(), + imp: vi.fn(), + default: { + info: vi.fn(), + warn: vi.fn(), + err: vi.fn(), + imp: vi.fn(), + }, +})); + +// Gracefully close ORM database connections after tests run to avoid open handle leaks +afterAll(async () => { + if (VARIAMOS_ORM) { + await VARIAMOS_ORM.close(); + } +}); From efca09339b37c9364664097fb4b3d11ee8bf67af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Bou=C3=A9?= Date: Fri, 7 Aug 2026 21:14:12 +0200 Subject: [PATCH 3/3] chore: finalize Vitest & Biome setup with strict types and clean CI --- .eslintrc.json | 114 - .github/workflows/ci.yml | 17 +- biome.json | 12 +- cspell.json | 3 + eslint.config.mjs | 149 -- package-lock.json | 2030 ++++++++--------- package.json | 65 +- src/CompositionRoot.ts | 26 +- src/DataProviders/BaseRepository.ts | 15 +- .../Metrics/MetricsRepository.ts | 5 +- .../MicroService/MicroServiceRepository.ts | 4 +- .../Permission/PermissionRepository.ts | 4 +- src/DataProviders/User/UserRepository.ts | 9 +- src/Domain/Bug/Repository/IBugRepository.ts | 3 +- .../Bug/Service/GitHubTokenResolver.test.ts | 4 +- src/Domain/Bug/UseCase/BugLifecycleUseCase.ts | 4 +- .../Bug/UseCase/BugSubmissionUseCase.ts | 7 +- src/Domain/Bug/UseCase/BugSyncUseCase.test.ts | 2 +- src/Domain/Bug/UseCase/BugSyncUseCase.ts | 2 +- src/Domain/Metrics/Entity/Metric.ts | 6 - .../User/UseCase/UserPasswordUseCase.test.ts | 14 +- src/EntryPoints/AuthRouter.test.ts | 19 +- src/EntryPoints/AuthRouter.ts | 8 +- src/EntryPoints/BugRouter.spec.ts | 5 +- src/EntryPoints/BugRouter.ts | 4 +- src/EntryPoints/ConfigurationRouter.test.ts | 2 +- src/EntryPoints/CountriesV1Router.test.ts | 5 +- src/EntryPoints/CountriesV1Router.ts | 4 +- src/EntryPoints/MetricsV1Router.test.ts | 5 +- src/EntryPoints/MetricsV1Router.ts | 5 +- src/EntryPoints/MicroServicesV1Router.test.ts | 5 +- src/EntryPoints/MicroServicesV1Router.ts | 2 +- src/EntryPoints/PermissionsV1Router.test.ts | 5 +- src/EntryPoints/PermissionsV1Router.ts | 8 +- .../RolePermissionsV1Router.test.ts | 5 +- src/EntryPoints/RolePermissionsV1Router.ts | 12 +- src/EntryPoints/RolesV1Router.test.ts | 5 +- src/EntryPoints/RolesV1Router.ts | 6 +- src/EntryPoints/UserRolesV1Router.test.ts | 5 +- src/EntryPoints/UserRolesV1Router.ts | 6 +- src/EntryPoints/UsersV1Router.test.ts | 7 +- src/EntryPoints/UsersV1Router.ts | 2 +- src/EntryPoints/VisitsV1Router.test.ts | 5 +- src/EntryPoints/VisitsV1Router.ts | 4 +- src/EntryPoints/errorMapper.test.ts | 2 +- src/EntryPoints/errorMapper.ts | 2 +- src/EntryPoints/index.ts | 68 +- src/Infrastructure/Mail/MailService.ts | 2 +- src/common/EnvVars.ts | 2 - src/index.ts | 8 +- src/server.ts | 37 +- tsconfig.json | 12 +- vitest.config.ts | 3 +- vitest.setup.ts | 10 +- 54 files changed, 1144 insertions(+), 1631 deletions(-) delete mode 100644 .eslintrc.json delete mode 100644 eslint.config.mjs diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index b892588..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:node/recommended", - "plugin:prettier/recommended" - ], - "parserOptions": { - "project": "./tsconfig.json" - }, - "rules": { - "@typescript-eslint/explicit-member-accessibility": "warn", - "@typescript-eslint/no-misused-promises": 0, - "@typescript-eslint/no-floating-promises": 0, - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/no-non-null-assertion": "warn", - "@typescript-eslint/no-unused-vars": [ - "warn", - { "argsIgnorePattern": "^_" } - ], - "no-restricted-syntax": [ - "error", - { - "selector": "TSAsExpression[expression.type='TSAsExpression']", - "message": "Double assertions (e.g., 'as unknown as T') are forbidden. Cast directly or use explicit mapping functions." - }, - { - "selector": "TSUnknownKeyword", - "message": "The 'unknown' type is forbidden. Use concrete types, generics (T), or 'void' for empty values. If you really think you need 'unknown' for a specific exception, disable the linter on that line using '// eslint-disable-next-line no-restricted-syntax'." - } - ], - "no-restricted-imports": [ - "error", - { - "patterns": [ - { - "group": ["**/../../*"], - "message": "Please use the @src alias instead of deep relative imports (../../)." - } - ] - } - ], - "no-console": [ - "error", - { "allow": ["warn", "error"] } - ], - "no-extra-boolean-cast": 0, - "node/no-process-env": 1, - "node/no-unsupported-features/es-syntax": [ - "error", - { "ignores" : ["modules"] } - ], - "node/no-missing-import": 0, - "node/no-unpublished-import": 0, - "prettier/prettier": [ - "error", - { - "endOfLine": "auto" - } - ] - }, - "settings": { - "node": { - "tryExtensions": [".js", ".json", ".node", ".ts"] - } - }, - "overrides": [ - { - "files": ["src/Domain/**/*.ts"], - "rules": { - "no-restricted-imports": [ - "error", - { - "patterns": [ - { - "group": ["@src/DataProviders/**", "@src/EntryPoints/**", "@src/Infrastructure/**"], - "message": "The Domain layer must be pure. Do not import from DataProviders, EntryPoints, or Infrastructure. Use Dependency Injection." - }, - { - "group": ["**/../../*"], - "message": "Please use the @src alias instead of deep relative imports (../../)." - } - ] - } - ] - } - }, - { - "files": ["**/*.spec.ts", "**/*.test.ts"], - "plugins": ["jest"], - "extends": ["plugin:jest/recommended"], - "env": { - "jest/globals": true - }, - "rules": { - "jest/no-disabled-tests": "warn", - "jest/no-focused-tests": "error", - "jest/no-identical-title": "error", - "jest/expect-expect": "error", - "@typescript-eslint/no-unsafe-member-access": "off", - "@typescript-eslint/no-unsafe-assignment": "off", - "@typescript-eslint/no-unsafe-call": "off", - "@typescript-eslint/no-unsafe-return": "off", - "@typescript-eslint/unbound-method": "off", - "no-restricted-syntax": "off" - } - } - ] -} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 446679a..8769369 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,22 +40,9 @@ jobs: run: | npm audit --audit-level=high - - name: Check code formatting (Prettier) + - name: Run linter and formatter (Biome) run: | - npx prettier --check "src/**/*.ts" - - - name: Cache ESLint - uses: actions/cache@v6 - with: - path: .eslintcache - key: ${{ runner.os }}-eslint-${{ hashFiles('package-lock.json') }}-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-eslint-${{ hashFiles('package-lock.json') }}- - ${{ runner.os }}-eslint- - - - name: Run linter (ESLint) - run: | - npm run lint -- --cache --cache-location .eslintcache + npm run lint - name: Verify TypeScript types run: | diff --git a/biome.json b/biome.json index 808b390..6dc3ba0 100644 --- a/biome.json +++ b/biome.json @@ -1,12 +1,18 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.7/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, "files": { - "ignore": ["dist/**", "coverage/**", ".stryker-tmp/**", "node_modules/**"] + "includes": [ + "**", + "!dist", + "!coverage", + "!.stryker-tmp", + "!node_modules" + ] }, "formatter": { "enabled": true, @@ -18,7 +24,7 @@ "linter": { "enabled": true, "rules": { - "recommended": true, + "preset": "recommended", "suspicious": { "noExplicitAny": "error" }, diff --git a/cspell.json b/cspell.json index 3f108a9..c91ff17 100644 --- a/cspell.json +++ b/cspell.json @@ -15,6 +15,9 @@ "stryker", "eslint", "prettier", + "biome", + "vitest", + "taze", "commitlint", "lintstaged", "dockerode", diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 5a537db..0000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,149 +0,0 @@ -import eslint from '@eslint/js'; -import tsParser from '@typescript-eslint/parser'; -import tsPlugin from '@typescript-eslint/eslint-plugin'; -import nodePlugin from 'eslint-plugin-n'; -import prettierPlugin from 'eslint-plugin-prettier'; -import jestPlugin from 'eslint-plugin-jest'; -import globals from 'globals'; - -export default [ - // Global ignores (replaces .eslintignore) - { - ignores: ['dist/**', 'coverage/**', 'node_modules/**', '.stryker-tmp/**'], - }, - // Base configuration - { - files: ['**/*.ts', '**/*.js'], - languageOptions: { - parser: tsParser, - parserOptions: { - project: './tsconfig.json', - }, - globals: { - ...globals.node, - }, - }, - plugins: { - '@typescript-eslint': tsPlugin, - 'n': nodePlugin, - 'node': nodePlugin, - 'prettier': prettierPlugin, - }, - settings: { - node: { - tryExtensions: ['.js', '.json', '.node', '.ts'], - }, - }, - rules: { - // Base ESLint recommended rules - ...eslint.configs.recommended.rules, - - // TypeScript eslint recommended overrides - ...tsPlugin.configs.recommended.rules, - ...tsPlugin.configs['recommended-requiring-type-checking']?.rules, - - // Node plugin recommended overrides - ...nodePlugin.configs.recommended.rules, - - // Custom Rules - '@typescript-eslint/explicit-member-accessibility': 'warn', - '@typescript-eslint/no-misused-promises': 0, - '@typescript-eslint/no-floating-promises': 0, - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-non-null-assertion': 'warn', - '@typescript-eslint/no-unnecessary-type-assertion': 'off', - '@typescript-eslint/no-base-to-string': 'off', - 'no-undef': 'off', - '@typescript-eslint/no-unused-vars': [ - 'warn', - { argsIgnorePattern: '^_' } - ], - 'no-restricted-syntax': [ - 'error', - { - selector: "TSAsExpression[expression.type='TSAsExpression']", - message: "Double assertions (e.g., 'as unknown as T') are forbidden. Cast directly or use explicit mapping functions." - }, - { - selector: "TSUnknownKeyword", - message: "The 'unknown' type is forbidden. Use concrete types, generics (T), or 'void' for empty values. If you really think you need 'unknown' for a specific exception, disable the linter on that line using '// eslint-disable-next-line no-restricted-syntax'." - } - ], - 'no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['**/../../*'], - message: 'Please use the @src alias instead of deep relative imports (../../).' - } - ] - } - ], - 'no-console': [ - 'error', - { allow: ['warn', 'error'] } - ], - 'no-extra-boolean-cast': 0, - 'node/no-process-env': 1, - 'node/no-unsupported-features/es-syntax': [ - 'error', - { ignores: ['modules'] } - ], - 'node/no-missing-import': 0, - 'node/no-unpublished-import': 0, - 'prettier/prettier': [ - 'error', - { - endOfLine: 'auto' - } - ] - } - }, - // Domain layer specific rules - { - files: ['src/Domain/**/*.ts'], - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['@src/DataProviders/**', '@src/EntryPoints/**', '@src/Infrastructure/**'], - message: 'The Domain layer must be pure. Do not import from DataProviders, EntryPoints, or Infrastructure. Use Dependency Injection.' - }, - { - group: ['**/../../*'], - message: 'Please use the @src alias instead of deep relative imports (../../).' - } - ] - } - ] - } - }, - // Test files specific configuration - { - files: ['**/*.spec.ts', '**/*.test.ts'], - plugins: { - jest: jestPlugin, - }, - languageOptions: { - globals: { - ...jestPlugin.environments.globals.globals, - }, - }, - rules: { - ...jestPlugin.configs.recommended.rules, - 'jest/no-disabled-tests': 'warn', - 'jest/no-focused-tests': 'error', - 'jest/no-identical-title': 'error', - 'jest/expect-expect': 'error', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-assignment': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/unbound-method': 'off', - 'no-restricted-syntax': 'off' - } - } -]; diff --git a/package-lock.json b/package-lock.json index fe216e5..9186c3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,81 +9,93 @@ "version": "0.0.0", "dependencies": { "@variamosple/variamos-security": "^0.0.15", - "axios": "^1.7.7", + "axios": "^1.19.0", "bcrypt": "^6.0.0", "cookie": "^2.0.1", - "cookie-parser": "~1.4.4", - "cors": "^2.8.5", + "cookie-parser": "~1.4.7", + "cors": "^2.8.6", "dockerode": "^5.0.1", "dotenv": "^17.4.2", "express": "^5.2.1", "google-auth-library": "^11.0.0", "helmet": "^8.3.0", "jet-logger": "^2.2.3", - "module-alias": "^2.2.3", + "module-alias": "^2.3.4", "morgan": "^1.11.0", - "multer": "^2.1.1", - "nodemailer": "^9.0.3", + "multer": "^2.2.0", + "nodemailer": "^9.0.5", "pg": "^8.22.0", "sequelize": "^6.37.8", "ts-command-line-args": "^2.5.1", "uuid": "^14.0.1", - "ws": "^8.21.1" + "ws": "^8.21.3" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", - "@commitlint/cli": "^21.0.0", - "@commitlint/config-conventional": "^21.0.0", + "@biomejs/biome": "^2.5.7", + "@commitlint/cli": "^21.2.1", + "@commitlint/config-conventional": "^21.2.0", "@stryker-mutator/core": "^9.6.1", "@stryker-mutator/typescript-checker": "^9.6.1", "@stryker-mutator/vitest-runner": "^9.6.1", "@types/bcrypt": "^6.0.0", - "@types/cookie-parser": "^1.4.7", - "@types/cors": "^2.8.17", + "@types/cookie-parser": "^1.4.10", + "@types/cors": "^2.8.19", "@types/dockerode": "^4.0.1", "@types/express": "^5.0.6", "@types/fs-extra": "^11.0.4", - "@types/jest": "^30.0.0", - "@types/morgan": "^1.9.9", - "@types/multer": "^2.1.0", - "@types/node": "^24.0.0", - "@types/nodemailer": "^8.0.0", - "@types/supertest": "^7.2.0", + "@types/morgan": "^1.9.10", + "@types/multer": "^2.2.0", + "@types/node": "^24.13.3", + "@types/nodemailer": "^8.0.1", + "@types/supertest": "^7.2.1", "@types/ws": "^8.18.1", - "@vitest/coverage-v8": "^3.0.5", + "@vitest/coverage-v8": "^4.1.10", "cspell": "^10.0.1", "dependency-cruiser": "^18.1.1", "fs-extra": "^11.4.0", "husky": "^9.1.7", - "knip": "^6.24.0", + "knip": "^6.32.0", "lint-staged": "^17.3.0", "nodemon": "^3.1.14", "supertest": "^7.2.2", + "taze": "^0.18.0", "ts-node": "^10.9.2", - "tsc-alias": "^1.8.10", + "tsc-alias": "^1.9.1", "tsconfig-paths": "^4.2.0", - "tsx": "^4.19.2", - "typescript": "^5.8.2", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.5", - "vitest-mock-extended": "^2.0.1" + "tsx": "^4.23.11", + "typescript": "^6.0.3", + "vite-tsconfig-paths": "^6.1.1", + "vitest": "^4.1.10", + "vitest-mock-extended": "^5.1.1" }, "engines": { "node": ">=24.0.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "node_modules/@antfu/ni": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/@antfu/ni/-/ni-0.23.2.tgz", + "integrity": "sha512-FSEVWXvwroExDXUu8qV6Wqp2X3D1nJ0Li4LFymCyvCVrm7I3lNfG0zZWSWvGU1RE7891eTnFTyh31L3igOwNKQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "license": "MIT", + "bin": { + "na": "bin/na.mjs", + "nci": "bin/nci.mjs", + "ni": "bin/ni.mjs", + "nlx": "bin/nlx.mjs", + "nr": "bin/nr.mjs", + "nu": "bin/nu.mjs", + "nun": "bin/nun.mjs" + } + }, + "node_modules/@antfu/utils": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" } }, "node_modules/@babel/code-frame": { @@ -624,11 +636,10 @@ "license": "Apache-2.0" }, "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.7.tgz", + "integrity": "sha512-zr8K/DcY5tYsQOQwqMJ0AWElo6QgmgNI7idXgXLhevVszlt8RGVpesEJPqx3ThazLaOwjJ5Y8fz3BtH5fGZNsw==", "dev": true, - "hasInstallScript": true, "license": "MIT OR Apache-2.0", "bin": { "biome": "bin/biome" @@ -641,20 +652,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" + "@biomejs/cli-darwin-arm64": "2.5.7", + "@biomejs/cli-darwin-x64": "2.5.7", + "@biomejs/cli-linux-arm64": "2.5.7", + "@biomejs/cli-linux-arm64-musl": "2.5.7", + "@biomejs/cli-linux-x64": "2.5.7", + "@biomejs/cli-linux-x64-musl": "2.5.7", + "@biomejs/cli-win32-arm64": "2.5.7", + "@biomejs/cli-win32-x64": "2.5.7" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.7.tgz", + "integrity": "sha512-vxo/Ls3/PYdQWyLhYYcgMOCzQypAjcY+iihS8M0wW03l16TCLW4zqZzGo75gm1VdCMj38hTVZ31KBWrZ4G9dJw==", "cpu": [ "arm64" ], @@ -669,9 +680,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.7.tgz", + "integrity": "sha512-Cd3Ga61amT/Yl/0x8elP5hhGYaFy4bw6WuysTgf7oo8TA5tJ5A1k+DkVoJ2BHbTVil51gTX9VPzArnrlLJ3Kyg==", "cpu": [ "x64" ], @@ -686,9 +697,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.7.tgz", + "integrity": "sha512-rR2QE0yF2GYSuYuKIa7pKvODGJqnOH+2eDREAM8wV+mWKSkMQKdAp4zXEZfTaxY8PMoNONnpgSWcBCyLDPDOKg==", "cpu": [ "arm64" ], @@ -706,9 +717,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.7.tgz", + "integrity": "sha512-xPI5yB6XlpDbNkS+bm1t42olw5c4l3UrlOmLg7KtLJvjvkNF/1V4tnUgfkylGIeb3u/T+BzMGYqgQhzjAoJzuQ==", "cpu": [ "arm64" ], @@ -726,9 +737,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.7.tgz", + "integrity": "sha512-FQgqJhscrqJUFptGaRSUJWlXAExwWcDwLuK49dvKfkQ1bB5SEEyFssnsxQY83Xm6jR0EbbX3+8+D5bfvYqUG2Q==", "cpu": [ "x64" ], @@ -746,9 +757,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.7.tgz", + "integrity": "sha512-rE5VZi+qtmPgQH+l7jVxYoZ18b/TiHEhulhMpjmCZH1PltSbjRcxNWywC3HZ9tYottG7ORkeTtoscBilKSBm0g==", "cpu": [ "x64" ], @@ -766,9 +777,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.7.tgz", + "integrity": "sha512-Oq4x0CCwP4jirrcTywXs5kOGZ4v5vuEP+gWrbtjApOA2CL9F3F9GlIdQIci8AKSCa/zURanMRpX/4wQ7Am6hHg==", "cpu": [ "arm64" ], @@ -783,9 +794,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.7.tgz", + "integrity": "sha512-V+0wu/nrj2S+MhP4EQ0uHNolP0IALEsz45pg0WoKkHfDeh0+ItHwP/p7bX5RPoMOl9NkpHYWdYPhIcy2mACHvQ==", "cpu": [ "x64" ], @@ -2752,129 +2763,6 @@ } } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/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, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "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": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -3709,17 +3597,6 @@ "@noble/hashes": "^1.1.5" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4202,13 +4079,6 @@ "url": "https://ko-fi.com/dangreen" } }, - "node_modules/@sinclair/typebox": { - "version": "0.34.52", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", - "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", - "dev": true, - "license": "MIT" - }, "node_modules/@sindresorhus/merge-streams": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", @@ -4222,6 +4092,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@stryker-mutator/api": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-9.6.1.tgz", @@ -4602,44 +4479,6 @@ "dev": true, "license": "MIT" }, - "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": { - "@types/istanbul-lib-coverage": "*" - } - }, - "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": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "30.0.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", - "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^30.0.0", - "pretty-format": "^30.0.0" - } - }, "node_modules/@types/jsonfile": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", @@ -4764,13 +4603,6 @@ "dev": true, "license": "MIT" }, - "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/superagent": { "version": "8.1.11", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.11.tgz", @@ -4811,23 +4643,6 @@ "@types/node": "*" } }, - "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": { - "@types/yargs-parser": "*" - } - }, - "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" - }, "node_modules/@variamosple/variamos-security": { "version": "0.0.15", "resolved": "https://registry.npmjs.org/@variamosple/variamos-security/-/variamos-security-0.0.15.tgz", @@ -4843,32 +4658,29 @@ "link": true }, "node_modules/@vitest/coverage-v8": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz", - "integrity": "sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", - "ast-v8-to-istanbul": "^0.3.3", - "debug": "^4.4.1", + "@vitest/utils": "4.1.10", + "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.6", - "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.17", - "magicast": "^0.3.5", - "std-env": "^3.9.0", - "test-exclude": "^7.0.1", - "tinyrainbow": "^2.0.0" + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.2.7", - "vitest": "3.2.7" + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -4886,55 +4698,41 @@ "node": ">=18" } }, - "node_modules/@vitest/coverage-v8/node_modules/test-exclude": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", - "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^10.2.2" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@vitest/expect": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", - "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/mocker": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", - "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.7", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -4946,42 +4744,42 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", - "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", - "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", - "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", "pathe": "^2.0.3" }, "funding": { @@ -4989,28 +4787,25 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", - "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", - "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -5265,9 +5060,9 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz", - "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz", + "integrity": "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==", "dev": true, "license": "MIT", "dependencies": { @@ -5569,6 +5364,22 @@ "node": ">=10.0.0" } }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -5589,16 +5400,6 @@ "node": ">= 0.8" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -5660,18 +5461,11 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -5728,16 +5522,6 @@ "dev": true, "license": "MIT" }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -5782,22 +5566,6 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC" }, - "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": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -6536,16 +6304,6 @@ } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -6555,6 +6313,13 @@ "node": ">=4.0.0" } }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6632,6 +6397,13 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -6738,13 +6510,6 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -6845,9 +6610,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "dev": true, "license": "MIT" }, @@ -7013,24 +6778,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/expect-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", @@ -7363,23 +7110,6 @@ } } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", @@ -7685,61 +7415,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "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": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global-directory": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz", @@ -8056,8 +7731,510 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/inflection": { - "version": "1.13.4", + "node_modules/importx": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/importx/-/importx-0.5.2.tgz", + "integrity": "sha512-YEwlK86Ml5WiTxN/ECUYC5U7jd1CisAVw7ya4i9ZppBoHfFkT2+hChhr3PE2fYxUKLkNyivxEQpa5Ruil1LJBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "debug": "^4.4.0", + "esbuild": "^0.20.2 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "jiti": "^2.4.2", + "pathe": "^2.0.3", + "tsx": "^4.19.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/importx/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/importx/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/inflection": { + "version": "1.13.4", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", "engines": [ @@ -8324,21 +8501,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", @@ -8353,119 +8515,6 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", - "picomatch": "^4.0.3", - "pretty-format": "30.4.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "jest-util": "30.4.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.4.1", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jet-logger": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/jet-logger/-/jet-logger-2.2.3.tgz", @@ -8715,6 +8764,16 @@ "yaml": "^2.9.0" } }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", @@ -8740,13 +8799,6 @@ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8768,15 +8820,15 @@ } }, "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz", + "integrity": "sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "source-map-js": "^1.2.1" } }, "node_modules/make-dir": { @@ -8954,16 +9006,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -9243,6 +9285,13 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, "node_modules/node-forge": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", @@ -9436,6 +9485,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -9535,12 +9610,15 @@ "@oxc-resolver/binding-win32-x64-msvc": "11.24.2" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", "dev": true, - "license": "BlueOak-1.0.0" + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } }, "node_modules/pako": { "version": "2.2.0", @@ -9629,30 +9707,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/path-to-regexp": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", @@ -9680,16 +9734,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/pg": { "version": "8.22.0", "resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz", @@ -9880,35 +9924,6 @@ "node": ">=0.10.0" } }, - "node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "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": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/pretty-ms": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", @@ -10036,6 +10051,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-lit": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", @@ -10095,22 +10127,6 @@ "node": ">= 0.10" } }, - "node_modules/react-is-18": { - "name": "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" - }, - "node_modules/react-is-19": { - "name": "react-is", - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", - "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", - "dev": true, - "license": "MIT" - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -10737,29 +10753,6 @@ "nan": "^2.23.0" } }, - "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": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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", - "engines": { - "node": ">=8" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -10777,127 +10770,49 @@ } }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-format": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", - "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "license": "WTFPL OR MIT" - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/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/string-width/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width/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, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=10.0.0" } }, - "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==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" - }, + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.6.19" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "license": "WTFPL OR MIT" + }, + "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": { "ansi-regex": "^5.0.1" @@ -10906,16 +10821,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/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": { - "node": ">=8" - } - }, "node_modules/strip-ansi/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -10938,26 +10843,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/superagent": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", @@ -11104,6 +10989,35 @@ "node": ">=6" } }, + "node_modules/taze": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/taze/-/taze-0.18.0.tgz", + "integrity": "sha512-aL8g+4tZvfhsn147u9dRP2eUE2MV+HfJe1sAtSJp46b0Gd8AjyqlJ2uDwnJfM1XNv301Mvh98RkXQw27sco5tQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/ni": "^0.23.0", + "js-yaml": "^4.1.0", + "ofetch": "^1.4.1", + "package-manager-detector": "^0.2.2", + "tinyexec": "^0.3.1", + "unconfig": "^0.6.0", + "yargs": "^17.7.2" + }, + "bin": { + "taze": "bin/taze.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/taze/node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -11138,30 +11052,10 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -11322,28 +11216,6 @@ "node": "^12.20.0 || >=14" } }, - "node_modules/tsconfck": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", - "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", - "deprecated": "unmaintained", - "dev": true, - "license": "MIT", - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -11492,9 +11364,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -11514,6 +11386,13 @@ "node": ">=8" } }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, "node_modules/unbash": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/unbash/-/unbash-4.0.7.tgz", @@ -11524,6 +11403,21 @@ "node": ">=14" } }, + "node_modules/unconfig": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.6.1.tgz", + "integrity": "sha512-cVU+/sPloZqOyJEAfNwnQSFCzFrZm85vcVkryH7lnlB/PiTycUkAjt5Ds79cfIshGOZ+M5v3PBDnKgpmlE5DtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^8.1.0", + "defu": "^6.1.4", + "importx": "^0.5.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", @@ -11726,33 +11620,10 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vite-tsconfig-paths": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", - "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.1.1.tgz", + "integrity": "sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==", "dev": true, "license": "MIT", "dependencies": { @@ -11762,73 +11633,104 @@ }, "peerDependencies": { "vite": "*" + } + }, + "node_modules/vite-tsconfig-paths/node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "deprecated": "unmaintained", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" }, "peerDependenciesMeta": { - "vite": { + "typescript": { "optional": true } } }, "node_modules/vitest": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", - "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.7", - "@vitest/ui": "3.2.7", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { @@ -11839,30 +11741,26 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, "node_modules/vitest-mock-extended": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vitest-mock-extended/-/vitest-mock-extended-2.0.2.tgz", - "integrity": "sha512-n3MBqVITKyclZ0n0y66hkT4UiiEYFQn9tteAnIxT0MPz1Z8nFcPUG3Cf0cZOyoPOj/cq6Ab1XFw2lM/qM5EDWQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/vitest-mock-extended/-/vitest-mock-extended-5.1.1.tgz", + "integrity": "sha512-k5Ji2+t4+nsdepXeakCkilyKydtgaULtP0HsjwQGIZsYr5hDTqrwCtC0+Sh0YBKUS7cY/Wxplf7SVjcZstTIMQ==", "dev": true, "license": "MIT", "dependencies": { - "ts-essentials": ">=10.0.0" + "ts-essentials": "^10.2.1" }, "peerDependencies": { - "typescript": "3.x || 4.x || 5.x", - "vitest": ">=2.0.0" + "typescript": "3.x || 4.x || 5.x || 6.x || 7.x", + "vitest": ">=4.0.0" } }, - "node_modules/vitest/node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/vscode-languageserver-textdocument": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", @@ -11980,94 +11878,6 @@ "node": ">=8" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "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": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 5e0e371..582d38f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "lint": "biome check src/", "lint:diff": "biome check --changed src/", "lint:diff:fix": "biome check --write --changed src/", + "lint:fix": "biome check --write --unsafe src/", "fix:all": "biome check --write src/", "start": "node ./dist/index.js --env=production", "dev": "npx tsx watch src/index.ts", @@ -20,75 +21,76 @@ "prepare": "husky", "check-arch": "dependency-cruiser --config .dependency-cruiser.cjs src/", "typecheck": "tsc --noEmit", - "find-deadcode": "knip" + "find-deadcode": "knip", + "check-updates": "taze" }, "engines": { "node": ">=24.0.0" }, "dependencies": { "@variamosple/variamos-security": "^0.0.15", - "axios": "^1.7.7", + "axios": "^1.19.0", "bcrypt": "^6.0.0", "cookie": "^2.0.1", - "cookie-parser": "~1.4.4", - "cors": "^2.8.5", + "cookie-parser": "~1.4.7", + "cors": "^2.8.6", "dockerode": "^5.0.1", "dotenv": "^17.4.2", "express": "^5.2.1", "google-auth-library": "^11.0.0", "helmet": "^8.3.0", "jet-logger": "^2.2.3", - "module-alias": "^2.2.3", + "module-alias": "^2.3.4", "morgan": "^1.11.0", - "multer": "^2.1.1", - "nodemailer": "^9.0.3", + "multer": "^2.2.0", + "nodemailer": "^9.0.5", "pg": "^8.22.0", "sequelize": "^6.37.8", "ts-command-line-args": "^2.5.1", "uuid": "^14.0.1", - "ws": "^8.21.1" + "ws": "^8.21.3" }, "devDependencies": { - "@commitlint/cli": "^21.0.0", - "@commitlint/config-conventional": "^21.0.0", + "@biomejs/biome": "^2.5.7", + "@commitlint/cli": "^21.2.1", + "@commitlint/config-conventional": "^21.2.0", "@stryker-mutator/core": "^9.6.1", "@stryker-mutator/typescript-checker": "^9.6.1", "@stryker-mutator/vitest-runner": "^9.6.1", "@types/bcrypt": "^6.0.0", - "@types/cookie-parser": "^1.4.7", - "@types/cors": "^2.8.17", + "@types/cookie-parser": "^1.4.10", + "@types/cors": "^2.8.19", "@types/dockerode": "^4.0.1", "@types/express": "^5.0.6", "@types/fs-extra": "^11.0.4", - "@types/jest": "^30.0.0", - "@types/morgan": "^1.9.9", - "@types/multer": "^2.1.0", - "@types/node": "^24.0.0", - "@types/nodemailer": "^8.0.0", - "@types/supertest": "^7.2.0", + "@types/morgan": "^1.9.10", + "@types/multer": "^2.2.0", + "@types/node": "^24.13.3", + "@types/nodemailer": "^8.0.1", + "@types/supertest": "^7.2.1", "@types/ws": "^8.18.1", - "@vitest/coverage-v8": "^3.0.5", - "@biomejs/biome": "^1.9.4", + "@vitest/coverage-v8": "^4.1.10", "cspell": "^10.0.1", "dependency-cruiser": "^18.1.1", "fs-extra": "^11.4.0", "husky": "^9.1.7", - "vitest-mock-extended": "^2.0.1", - "knip": "^6.24.0", + "knip": "^6.32.0", "lint-staged": "^17.3.0", "nodemon": "^3.1.14", "supertest": "^7.2.2", + "taze": "^0.18.0", "ts-node": "^10.9.2", - "tsc-alias": "^1.8.10", + "tsc-alias": "^1.9.1", "tsconfig-paths": "^4.2.0", - "tsx": "^4.19.2", - "typescript": "^5.8.2", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.5" + "tsx": "^4.23.11", + "typescript": "^6.0.3", + "vite-tsconfig-paths": "^6.1.1", + "vitest": "^4.1.10", + "vitest-mock-extended": "^5.1.1" }, "overrides": { - "uuid": "^14.0.1", - "qs": "^6.15.2" + "qs": "^6.15.3", + "uuid": "^14.0.1" }, "allowScripts": { "bcrypt@6.0.0": true, @@ -96,7 +98,8 @@ "protobufjs@7.6.5": true, "ssh2@1.17.0": true, "unrs-resolver@1.12.2": true, - "esbuild@0.28.1": true, - "@biomejs/biome@1.9.4": true + "@biomejs/biome@1.9.4": true, + "esbuild@0.25.12": true, + "esbuild@0.28.1": true } } diff --git a/src/CompositionRoot.ts b/src/CompositionRoot.ts index 05605a5..6849973 100644 --- a/src/CompositionRoot.ts +++ b/src/CompositionRoot.ts @@ -9,14 +9,6 @@ import { RoleRepositoryImpl } from "./DataProviders/Role/RoleRepository.js"; import { UserRepositoryImpl } from "./DataProviders/User/UserRepository.js"; import { UserRoleRepositoryImpl } from "./DataProviders/User/UserRoleRepository.js"; import { VisitRepositoryImpl } from "./DataProviders/Visit/VisitRepository.js"; - -// User Use Cases -import { UserAuthUseCase } from "./Domain/User/UseCase/UserAuthUseCase.js"; -import { UserManagementUseCase } from "./Domain/User/UseCase/UserManagementUseCase.js"; -import { UserPasswordUseCase } from "./Domain/User/UseCase/UserPasswordUseCase.js"; -import { UserQueryUseCase } from "./Domain/User/UseCase/UserQueryUseCase.js"; -import { UserRoleUseCase } from "./Domain/User/UseCase/UserRoleUseCase.js"; - // Bug Use Cases import { GitHubTokenResolver } from "./Domain/Bug/Service/GitHubTokenResolver.js"; import { BugAttachmentUseCase } from "./Domain/Bug/UseCase/BugAttachmentUseCase.js"; @@ -24,18 +16,22 @@ import { BugLifecycleUseCase } from "./Domain/Bug/UseCase/BugLifecycleUseCase.js import { BugQueryUseCase } from "./Domain/Bug/UseCase/BugQueryUseCase.js"; import { BugSubmissionUseCase } from "./Domain/Bug/UseCase/BugSubmissionUseCase.js"; import { BugSyncUseCase } from "./Domain/Bug/UseCase/BugSyncUseCase.js"; - -// Permission & Role Use Cases -import { PermissionUseCase } from "./Domain/Permission/UseCase/PermissionUseCase.js"; -import { RoleManagementUseCase } from "./Domain/Role/UseCase/RoleManagementUseCase.js"; -import { RolePermissionUseCase } from "./Domain/Role/UseCase/RolePermissionUseCase.js"; -import { RoleQueryUseCase } from "./Domain/Role/UseCase/RoleQueryUseCase.js"; - import { CountriesQueryUseCase } from "./Domain/Countries/UseCase/CountriesQueryUseCase.js"; // Other Use Cases import { MetricsQueryUseCase } from "./Domain/Metrics/UseCase/MetricsQueryUseCase.js"; import { MicroServiceManagementUseCase } from "./Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; import { MicroServiceQueryUseCase } from "./Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +// Permission & Role Use Cases +import { PermissionUseCase } from "./Domain/Permission/UseCase/PermissionUseCase.js"; +import { RoleManagementUseCase } from "./Domain/Role/UseCase/RoleManagementUseCase.js"; +import { RolePermissionUseCase } from "./Domain/Role/UseCase/RolePermissionUseCase.js"; +import { RoleQueryUseCase } from "./Domain/Role/UseCase/RoleQueryUseCase.js"; +// User Use Cases +import { UserAuthUseCase } from "./Domain/User/UseCase/UserAuthUseCase.js"; +import { UserManagementUseCase } from "./Domain/User/UseCase/UserManagementUseCase.js"; +import { UserPasswordUseCase } from "./Domain/User/UseCase/UserPasswordUseCase.js"; +import { UserQueryUseCase } from "./Domain/User/UseCase/UserQueryUseCase.js"; +import { UserRoleUseCase } from "./Domain/User/UseCase/UserRoleUseCase.js"; import { VisitUseCase } from "./Domain/Visit/UseCase/VisitUseCase.js"; import { GitHubIssuesServiceInstance } from "./Infrastructure/GitHub/GitHubIssuesService.js"; diff --git a/src/DataProviders/BaseRepository.ts b/src/DataProviders/BaseRepository.ts index 131d7fd..ab7b807 100644 --- a/src/DataProviders/BaseRepository.ts +++ b/src/DataProviders/BaseRepository.ts @@ -1,16 +1,25 @@ export interface Replacements { - [key: string]: string | number | boolean | null | Date | string[] | number[]; + [key: string]: + | string + | number + | boolean + | null + | undefined + | Date + | string[] + | number[]; } export abstract class BaseRepository { - initializeReplacements(filter: Replacements) { + initializeReplacements(filter: object | undefined | null) { if (!filter) { return {}; } return Object.entries(filter).reduce( (result, [key, value]) => { - result[key] = value === undefined ? null : value; + result[key] = + value === undefined ? null : (value as Replacements[string]); return result; }, diff --git a/src/DataProviders/Metrics/MetricsRepository.ts b/src/DataProviders/Metrics/MetricsRepository.ts index 4196250..cfca364 100644 --- a/src/DataProviders/Metrics/MetricsRepository.ts +++ b/src/DataProviders/Metrics/MetricsRepository.ts @@ -55,7 +55,7 @@ export class MetricsRepositoryImpl }[]; } | undefined; - if (!resObj || !resObj.data) return []; + if (!resObj?.data) return []; return resObj.data.map( ({ id, title, chartType, defaultFilter, filters, labelKey, data }) => Metric.builder() @@ -143,8 +143,7 @@ export class MetricsRepositoryImpl }; } | undefined; - if (!resObj || !resObj.data) - throw new Error("Invalid database response format"); + if (!resObj?.data) throw new Error("Invalid database response format"); const { id, title, diff --git a/src/DataProviders/MicroService/MicroServiceRepository.ts b/src/DataProviders/MicroService/MicroServiceRepository.ts index 2e3c7df..fbc8f10 100644 --- a/src/DataProviders/MicroService/MicroServiceRepository.ts +++ b/src/DataProviders/MicroService/MicroServiceRepository.ts @@ -3,12 +3,10 @@ import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { MicroService } from "@src/Domain/MicroService/Entity/MicroService.js"; import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; - +import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; import Docker from "dockerode"; import logger from "jet-logger"; -import type { IMicroServiceRepository } from "@src/Domain/MicroService/Repository/IMicroServiceRepository.js"; - export class MicroServiceRepositoryImpl implements IMicroServiceRepository { private dockerConnection: Docker; diff --git a/src/DataProviders/Permission/PermissionRepository.ts b/src/DataProviders/Permission/PermissionRepository.ts index 2ebb7ca..dad53f0 100644 --- a/src/DataProviders/Permission/PermissionRepository.ts +++ b/src/DataProviders/Permission/PermissionRepository.ts @@ -1,9 +1,9 @@ import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; -/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/explicit-member-accessibility */ import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; +import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; import VARIAMOS_ORM, { DB_SCHEMA } from "@src/Infrastructure/VariamosORM.js"; import logger from "jet-logger"; import { Op, QueryTypes, type WhereOptions } from "sequelize"; @@ -11,8 +11,6 @@ import { BaseRepository } from "../BaseRepository.js"; import { RolePermissionModel } from "../Role/RolePermission.js"; import { type PermissionAttributes, PermissionModel } from "./Permission.js"; -import type { IPermissionRepository } from "@src/Domain/Permission/Repository/IPermissionRepository.js"; - export class PermissionRepositoryImpl extends BaseRepository implements IPermissionRepository diff --git a/src/DataProviders/User/UserRepository.ts b/src/DataProviders/User/UserRepository.ts index 979bcb3..dd67590 100644 --- a/src/DataProviders/User/UserRepository.ts +++ b/src/DataProviders/User/UserRepository.ts @@ -291,12 +291,7 @@ export class UserRepositoryImpl const errorMessage = "Incorrect username or password."; - if ( - !dbUser || - !dbUser.password || - !dbUser.isEnabled || - dbUser.isDeleted - ) { + if (!dbUser?.password || !dbUser.isEnabled || dbUser.isDeleted) { return response.withError(DomainErrorCodes.INVALID_INPUT, errorMessage); } @@ -564,7 +559,7 @@ export class UserRepositoryImpl } private async enrichUserRolesAndPermissions(user: User) { - if (!user || !user.id) { + if (!user?.id) { return; } diff --git a/src/Domain/Bug/Repository/IBugRepository.ts b/src/Domain/Bug/Repository/IBugRepository.ts index 89df0b4..ccb63b3 100644 --- a/src/Domain/Bug/Repository/IBugRepository.ts +++ b/src/Domain/Bug/Repository/IBugRepository.ts @@ -1,12 +1,11 @@ import type { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import type { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import type { Bug } from "../Entity/Bug.js"; +import type { BugAttachment } from "../Entity/BugAttachment.js"; import type { BugFilter } from "../Entity/BugFilter.js"; import type { BugNote } from "../Entity/BugNote.js"; import type { BugStatusLog } from "../Entity/BugStatusLog.js"; -import type { BugAttachment } from "../Entity/BugAttachment.js"; - export interface IBugRepository { queryBugs(request: RequestModel): Promise>; queryLocalBugs( diff --git a/src/Domain/Bug/Service/GitHubTokenResolver.test.ts b/src/Domain/Bug/Service/GitHubTokenResolver.test.ts index f4cc522..121fa74 100644 --- a/src/Domain/Bug/Service/GitHubTokenResolver.test.ts +++ b/src/Domain/Bug/Service/GitHubTokenResolver.test.ts @@ -8,7 +8,9 @@ import { GitHubTokenResolver } from "./GitHubTokenResolver.js"; vi.mock("axios"); vi.mock("jet-logger"); vi.mock("crypto", async () => { - const actual = await vi.importActual("crypto"); + const actual = await vi.importActual< + typeof import("crypto") & { default: typeof import("crypto") } + >("crypto"); const mockCreateSign = vi.fn(); return { ...actual, diff --git a/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts b/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts index 2f4b7ca..0bf6d79 100644 --- a/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts +++ b/src/Domain/Bug/UseCase/BugLifecycleUseCase.ts @@ -108,8 +108,8 @@ export class BugLifecycleUseCase { if (data.category) bug.category = data.category; if (data.githubRepo) bug.githubRepo = data.githubRepo; - let gitIssueNumber: number | undefined = undefined; - let githubHtmlUrl: string | undefined = undefined; + let gitIssueNumber: number | undefined; + let githubHtmlUrl: string | undefined; if (data.status === "open" && !bug.gitIssueNumber && bug.githubRepo) { const gitHubToken = await this.tokenResolver.resolveGitHubToken( diff --git a/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts b/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts index 506dfc1..c2236c9 100644 --- a/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts +++ b/src/Domain/Bug/UseCase/BugSubmissionUseCase.ts @@ -98,8 +98,7 @@ export class BugSubmissionUseCase { ); } - let resolvedFile: { filePath: string; fileType: string } | undefined = - undefined; + let resolvedFile: { filePath: string; fileType: string } | undefined; if (data.file) { resolvedFile = { filePath: `/uploads/${data.file.filename}`, @@ -108,8 +107,8 @@ export class BugSubmissionUseCase { } let status = "pending"; - let gitIssueNumber: number | undefined = undefined; - let githubHtmlUrl: string | undefined = undefined; + let gitIssueNumber: number | undefined; + let githubHtmlUrl: string | undefined; if (data.githubRepo && data.createdById) { const gitHubToken = await this.tokenResolver.resolveGitHubToken( diff --git a/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts b/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts index e9d371c..b3a2d85 100644 --- a/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts +++ b/src/Domain/Bug/UseCase/BugSyncUseCase.test.ts @@ -631,7 +631,7 @@ describe("BugSyncUseCase", () => { const calls = mockBugRepository.saveOrUpdateBug.mock.calls; expect(calls.length).toBe(3); const thirdCall = calls[2]; - if (!thirdCall || !thirdCall[0] || !thirdCall[0].data) { + if (!thirdCall?.[0]?.data) { throw new Error("Expected third call to have data"); } const updatedAt = thirdCall[0].data.updatedAt; diff --git a/src/Domain/Bug/UseCase/BugSyncUseCase.ts b/src/Domain/Bug/UseCase/BugSyncUseCase.ts index 01b7981..dec9583 100644 --- a/src/Domain/Bug/UseCase/BugSyncUseCase.ts +++ b/src/Domain/Bug/UseCase/BugSyncUseCase.ts @@ -60,7 +60,7 @@ export class BugSyncUseCase { if (issue.pull_request) continue; let priority: "low" | "medium" | "high" = "medium"; - let category: string | undefined = undefined; + let category: string | undefined; if (issue.labels && Array.isArray(issue.labels)) { const labelNames = issue.labels.map((l) => l.name.toLowerCase()); if ( diff --git a/src/Domain/Metrics/Entity/Metric.ts b/src/Domain/Metrics/Entity/Metric.ts index c559525..41175c9 100644 --- a/src/Domain/Metrics/Entity/Metric.ts +++ b/src/Domain/Metrics/Entity/Metric.ts @@ -5,7 +5,6 @@ export class Metric { private defaultFilter: string; private filters?: string[]; private labelKey?: string; - // eslint-disable-next-line no-restricted-syntax private data: unknown; public constructor( @@ -15,7 +14,6 @@ export class Metric { defaultFilter: string, filters?: string[], labelKey?: string, - // eslint-disable-next-line no-restricted-syntax data?: unknown, ) { this.id = id; @@ -51,7 +49,6 @@ export class Metric { return this.labelKey; } - // eslint-disable-next-line no-restricted-syntax public getData(): unknown { return this.data; } @@ -80,7 +77,6 @@ class MetricBuilder { private defaultFilter!: string; private filters?: string[]; private labelKey?: string; - // eslint-disable-next-line no-restricted-syntax private data!: unknown; public getId(): string { @@ -137,12 +133,10 @@ class MetricBuilder { return this; } - // eslint-disable-next-line no-restricted-syntax public getData(): unknown { return this.data; } - // eslint-disable-next-line no-restricted-syntax public setData(data: unknown): MetricBuilder { this.data = data; return this; diff --git a/src/Domain/User/UseCase/UserPasswordUseCase.test.ts b/src/Domain/User/UseCase/UserPasswordUseCase.test.ts index 0bf8d50..c76e4f5 100644 --- a/src/Domain/User/UseCase/UserPasswordUseCase.test.ts +++ b/src/Domain/User/UseCase/UserPasswordUseCase.test.ts @@ -49,7 +49,7 @@ describe("UserPasswordUseCase", () => { describe("requestReset", () => { it("should request password reset successfully when user is found and active", async () => { mockUserRepository.getUserByEmail.mockResolvedValue(mockUser); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockResolvedValue("generated-token"); mockMailService.sendPasswordResetMail.mockResolvedValue(true); @@ -91,7 +91,7 @@ describe("UserPasswordUseCase", () => { it("should return empty response if token service throws validation error", async () => { mockUserRepository.getUserByEmail.mockResolvedValue(mockUser); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("User account is disabled.")); @@ -105,7 +105,7 @@ describe("UserPasswordUseCase", () => { it("should return SYSTEM_ERROR if mail service fails to send mail", async () => { mockUserRepository.getUserByEmail.mockResolvedValue(mockUser); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockResolvedValue("generated-token"); mockMailService.sendPasswordResetMail.mockResolvedValue(false); @@ -267,7 +267,7 @@ describe("UserPasswordUseCase", () => { mockUserRepository.queryById.mockResolvedValue( new ResponseModel("tx-1").withResponse(mockUser), ); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockResolvedValue("generated-token"); const loggerInfoSpy = vi @@ -335,7 +335,7 @@ describe("UserPasswordUseCase", () => { mockUserRepository.queryById.mockResolvedValue( new ResponseModel("tx-1").withResponse(mockUser), ); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("User account is disabled.")); @@ -382,7 +382,7 @@ describe("UserPasswordUseCase", () => { mockUserRepository.queryById.mockResolvedValue( new ResponseModel("tx-1").withResponse(mockUser), ); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("Unexpected token creation issue")); @@ -408,7 +408,7 @@ describe("UserPasswordUseCase", () => { it("should propagate errors in requestReset when token service throws general error", async () => { mockUserRepository.getUserByEmail.mockResolvedValue(mockUser); - const createTokenSpy = jest + const createTokenSpy = vi .spyOn(PasswordResetTokenService.prototype, "createResetToken") .mockRejectedValue(new Error("General system crash")); diff --git a/src/EntryPoints/AuthRouter.test.ts b/src/EntryPoints/AuthRouter.test.ts index 8323b01..ef6ac22 100644 --- a/src/EntryPoints/AuthRouter.test.ts +++ b/src/EntryPoints/AuthRouter.test.ts @@ -1,4 +1,4 @@ -// Mock google-auth-library as a standard class to bypass Jest resetMocks: true +// Mock google-auth-library as a standard class to bypass Vitest restoreMocks: true vi.mock("google-auth-library", () => { return { OAuth2Client: class { @@ -33,9 +33,14 @@ vi.mock("./errorMapper", async () => { }; }); +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; +import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; import { User } from "@src/Domain/User/Entity/User.js"; +import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; import { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; import { @@ -43,15 +48,13 @@ import { type UserPasswordUseCaseConfig, } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; -import EnvVars from "@src/common/EnvVars.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { - ResponseModel as SecurityResponseModel, - type SessionInfo, createJwt, getToken, hasPermissions, isSessionExpired, + ResponseModel as SecurityResponseModel, + type SessionInfo, sessionInfoToSessionUser, validateToken, } from "@variamosple/variamos-security"; @@ -59,14 +62,10 @@ import cookieParser from "cookie-parser"; import express from "express"; import logger from "jet-logger"; import supertest from "supertest"; +import { mock } from "vitest-mock-extended"; import { AUTH_ROUTE, createAuthRouter } from "./AuthRouter.js"; import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; -import type { IMailService } from "@src/Domain/Mail/IMailService.js"; -import type { IGuestRoleRepository } from "@src/Domain/Role/Repository/IGuestRoleRepository.js"; -import type { IUserRepository } from "@src/Domain/User/IUserRepository.js"; -import { mock } from "vitest-mock-extended"; - // Mock other dependencies vi.mock("@src/Domain/User/UseCase/UserAuthUseCase"); vi.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); diff --git a/src/EntryPoints/AuthRouter.ts b/src/EntryPoints/AuthRouter.ts index 228d549..b97373a 100644 --- a/src/EntryPoints/AuthRouter.ts +++ b/src/EntryPoints/AuthRouter.ts @@ -1,3 +1,5 @@ +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import type { Nullable } from "@src/Domain/Core/Entity/Nullable.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; @@ -13,14 +15,12 @@ import type { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.j import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; -import EnvVars from "@src/common/EnvVars.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { - type SessionUser, createJwt, getToken, hasPermissions, isSessionExpired, + type SessionUser, sessionInfoToSessionUser, validateToken, } from "@variamosple/variamos-security"; @@ -210,7 +210,7 @@ export function createAuthRouter( ); } - if (!!refreshedUser.errorCode || !refreshedUser.data) { + if (refreshedUser.errorCode || !refreshedUser.data) { return res .status(HttpStatusCodes.UNAUTHORIZED) .json( diff --git a/src/EntryPoints/BugRouter.spec.ts b/src/EntryPoints/BugRouter.spec.ts index 1dbf18a..7a9b19c 100644 --- a/src/EntryPoints/BugRouter.spec.ts +++ b/src/EntryPoints/BugRouter.spec.ts @@ -1,4 +1,5 @@ import { mock } from "vitest-mock-extended"; + const mockValidateSession = vi.fn(); vi.mock("@variamosple/variamos-security", () => ({ @@ -58,8 +59,8 @@ import multer from "multer"; import request from "supertest"; import { createBugRouter } from "./BugRouter.js"; -const mockLoggerInfo = vi.spyOn(logger, "info").mockImplementation(); -const mockLoggerErr = vi.spyOn(logger, "err").mockImplementation(); +const mockLoggerInfo = vi.spyOn(logger, "info").mockImplementation(() => {}); +const mockLoggerErr = vi.spyOn(logger, "err").mockImplementation(() => {}); const mockBugSubmissionUseCase = mock(); const mockBugLifecycleUseCase = mock(); diff --git a/src/EntryPoints/BugRouter.ts b/src/EntryPoints/BugRouter.ts index 4ebd2bb..6b011b5 100644 --- a/src/EntryPoints/BugRouter.ts +++ b/src/EntryPoints/BugRouter.ts @@ -1,3 +1,4 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { BugFilter } from "@src/Domain/Bug/Entity/BugFilter.js"; import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; @@ -5,7 +6,6 @@ import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { type SessionUser, validateSession, @@ -144,7 +144,7 @@ export function createBugRouter( githubRepo?: string; reporterEmail?: string; }; - let adminId: string | undefined = undefined; + let adminId: string | undefined; if ((req as RequestWithUser).user) { adminId = (req as RequestWithUser).user.id; } else { diff --git a/src/EntryPoints/ConfigurationRouter.test.ts b/src/EntryPoints/ConfigurationRouter.test.ts index 61a4388..4692ee4 100644 --- a/src/EntryPoints/ConfigurationRouter.test.ts +++ b/src/EntryPoints/ConfigurationRouter.test.ts @@ -1,5 +1,5 @@ -import type { Menu } from "@src/Domain/Menu/Entity/Menu.js"; import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import type { Menu } from "@src/Domain/Menu/Entity/Menu.js"; import express from "express"; import supertest from "supertest"; import { createConfigurationRouter } from "./ConfigurationRouter.js"; diff --git a/src/EntryPoints/CountriesV1Router.test.ts b/src/EntryPoints/CountriesV1Router.test.ts index 193f2c5..3caac8a 100644 --- a/src/EntryPoints/CountriesV1Router.test.ts +++ b/src/EntryPoints/CountriesV1Router.test.ts @@ -1,11 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createCountriesRouter } from "./CountriesV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createCountriesRouter } from "./CountriesV1Router.js"; // Mock dependencies vi.mock("@src/Domain/Countries/UseCase/CountriesQueryUseCase"); diff --git a/src/EntryPoints/CountriesV1Router.ts b/src/EntryPoints/CountriesV1Router.ts index 4daa8c8..9f820d0 100644 --- a/src/EntryPoints/CountriesV1Router.ts +++ b/src/EntryPoints/CountriesV1Router.ts @@ -1,9 +1,9 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; -import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; import { isAuthenticated } from "@variamosple/variamos-security"; import { Router } from "express"; import logger from "jet-logger"; diff --git a/src/EntryPoints/MetricsV1Router.test.ts b/src/EntryPoints/MetricsV1Router.test.ts index 71984da..b17f220 100644 --- a/src/EntryPoints/MetricsV1Router.test.ts +++ b/src/EntryPoints/MetricsV1Router.test.ts @@ -1,12 +1,11 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { Metric } from "@src/Domain/Metrics/Entity/Metric.js"; import { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createMetricsRouter } from "./MetricsV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createMetricsRouter } from "./MetricsV1Router.js"; // Mock dependencies vi.mock("@src/Domain/Metrics/UseCase/MetricsQueryUseCase"); diff --git a/src/EntryPoints/MetricsV1Router.ts b/src/EntryPoints/MetricsV1Router.ts index fdc3bee..8192ccd 100644 --- a/src/EntryPoints/MetricsV1Router.ts +++ b/src/EntryPoints/MetricsV1Router.ts @@ -1,11 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { MetricsFilter } from "@src/Domain/Metrics/Entity/MetricsFilter.js"; import type { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; import { hasPermissions } from "@variamosple/variamos-security"; - -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { type Request, Router } from "express"; import logger from "jet-logger"; import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; diff --git a/src/EntryPoints/MicroServicesV1Router.test.ts b/src/EntryPoints/MicroServicesV1Router.test.ts index 0b92cb3..e0d6954 100644 --- a/src/EntryPoints/MicroServicesV1Router.test.ts +++ b/src/EntryPoints/MicroServicesV1Router.test.ts @@ -1,14 +1,13 @@ import { Readable } from "node:stream"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; import { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createMicroServicesRouter } from "./MicroServicesV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createMicroServicesRouter } from "./MicroServicesV1Router.js"; // Mock dependencies vi.mock("@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase"); diff --git a/src/EntryPoints/MicroServicesV1Router.ts b/src/EntryPoints/MicroServicesV1Router.ts index 59b9527..2c6e4ac 100644 --- a/src/EntryPoints/MicroServicesV1Router.ts +++ b/src/EntryPoints/MicroServicesV1Router.ts @@ -1,10 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { MicroServiceFilter } from "@src/Domain/MicroService/Entity/MicroServiceFilter.js"; import type { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; import type { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; diff --git a/src/EntryPoints/PermissionsV1Router.test.ts b/src/EntryPoints/PermissionsV1Router.test.ts index 716ebec..c4afd34 100644 --- a/src/EntryPoints/PermissionsV1Router.test.ts +++ b/src/EntryPoints/PermissionsV1Router.test.ts @@ -1,13 +1,12 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; import { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createPermissionsRouter } from "./PermissionsV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createPermissionsRouter } from "./PermissionsV1Router.js"; // Mock dependencies vi.mock("@src/Domain/Permission/UseCase/PermissionUseCase"); diff --git a/src/EntryPoints/PermissionsV1Router.ts b/src/EntryPoints/PermissionsV1Router.ts index 9861fb3..6084ee5 100644 --- a/src/EntryPoints/PermissionsV1Router.ts +++ b/src/EntryPoints/PermissionsV1Router.ts @@ -1,10 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Permission } from "@src/Domain/Permission/Entity/Permission.js"; import { PermissionFilter } from "@src/Domain/Permission/Entity/PermissionFilter.js"; import type { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; @@ -119,7 +119,7 @@ export function createPermissionsRouter( const request = new RequestModel( transactionId, - Number.parseInt(permissionId), + Number.parseInt(permissionId, 10), ); const response = await permissionUseCase.deletePermission(request); @@ -158,7 +158,7 @@ export function createPermissionsRouter( const request = new RequestModel( transactionId, - Number.parseInt(permissionId), + Number.parseInt(permissionId, 10), ); const response = await permissionUseCase.queryById(request); @@ -208,7 +208,7 @@ export function createPermissionsRouter( let permission: Permission; try { - permission = new Permission(Number.parseInt(permissionId), name); + permission = new Permission(Number.parseInt(permissionId, 10), name); } catch (error) { return res .status(HttpStatusCodes.BAD_REQUEST) diff --git a/src/EntryPoints/RolePermissionsV1Router.test.ts b/src/EntryPoints/RolePermissionsV1Router.test.ts index a8c263f..686479d 100644 --- a/src/EntryPoints/RolePermissionsV1Router.test.ts +++ b/src/EntryPoints/RolePermissionsV1Router.test.ts @@ -1,13 +1,12 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; import { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createRolePermissionsRouter } from "./RolePermissionsV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createRolePermissionsRouter } from "./RolePermissionsV1Router.js"; // Mock dependencies vi.mock("@src/Domain/Role/UseCase/RolePermissionUseCase"); diff --git a/src/EntryPoints/RolePermissionsV1Router.ts b/src/EntryPoints/RolePermissionsV1Router.ts index d0eb5a7..0fe39bc 100644 --- a/src/EntryPoints/RolePermissionsV1Router.ts +++ b/src/EntryPoints/RolePermissionsV1Router.ts @@ -1,10 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { RolePermission } from "@src/Domain/Role/Entity/RolePermission.js"; import { RolePermissionFilter } from "@src/Domain/Role/Entity/RolePermissionFilter.js"; import type { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; @@ -37,7 +37,7 @@ export function createRolePermissionsRouter( } const filter: RolePermissionFilter = RolePermissionFilter.builder() - .setRoleId(Number.parseInt(roleId)) + .setRoleId(Number.parseInt(roleId, 10)) .setPageNumber(Number(pageNumber)) .setPageSize(Number(pageSize)) .build(); @@ -88,8 +88,8 @@ export function createRolePermissionsRouter( } const rolePermission: RolePermission = new RolePermission( - Number.parseInt(roleId), - Number.parseInt(permissionId), + Number.parseInt(roleId, 10), + Number.parseInt(permissionId, 10), ); const request = new RequestModel( @@ -139,8 +139,8 @@ export function createRolePermissionsRouter( } const rolePermission: RolePermission = new RolePermission( - Number.parseInt(roleId), - Number.parseInt(permissionId), + Number.parseInt(roleId, 10), + Number.parseInt(permissionId, 10), ); const request = new RequestModel( diff --git a/src/EntryPoints/RolesV1Router.test.ts b/src/EntryPoints/RolesV1Router.test.ts index f7a8553..4338e8c 100644 --- a/src/EntryPoints/RolesV1Router.test.ts +++ b/src/EntryPoints/RolesV1Router.test.ts @@ -1,14 +1,13 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Role } from "@src/Domain/Role/Entity/Role.js"; import { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; import { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createRolesRouter } from "./RolesV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createRolesRouter } from "./RolesV1Router.js"; // Mock dependencies vi.mock("@src/Domain/Role/UseCase/RoleQueryUseCase"); diff --git a/src/EntryPoints/RolesV1Router.ts b/src/EntryPoints/RolesV1Router.ts index 349ee3f..edf31b5 100644 --- a/src/EntryPoints/RolesV1Router.ts +++ b/src/EntryPoints/RolesV1Router.ts @@ -1,3 +1,4 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; @@ -5,12 +6,11 @@ import { Role } from "@src/Domain/Role/Entity/Role.js"; import { RoleFilter } from "@src/Domain/Role/Entity/RoleFilter.js"; import type { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; import type { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; -import { ROLE_PERMISSIONS_V1_ROUTE } from "./RolePermissionsV1Router.js"; import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; +import { ROLE_PERMISSIONS_V1_ROUTE } from "./RolePermissionsV1Router.js"; export const ROLES_V1_ROUTE = "/v1/roles"; @@ -200,7 +200,7 @@ export function createRolesRouter( let permission: Role; try { - permission = new Role(Number.parseInt(roleId), name); + permission = new Role(Number.parseInt(roleId, 10), name); } catch (error) { return res .status(HttpStatusCodes.BAD_REQUEST) diff --git a/src/EntryPoints/UserRolesV1Router.test.ts b/src/EntryPoints/UserRolesV1Router.test.ts index d338e5a..c63e908 100644 --- a/src/EntryPoints/UserRolesV1Router.test.ts +++ b/src/EntryPoints/UserRolesV1Router.test.ts @@ -1,13 +1,12 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { UserRole } from "@src/Domain/User/Entity/UserRole.js"; import { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createUserRolesRouter } from "./UserRolesV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createUserRolesRouter } from "./UserRolesV1Router.js"; // Mock dependencies vi.mock("@src/Domain/User/UseCase/UserRoleUseCase"); diff --git a/src/EntryPoints/UserRolesV1Router.ts b/src/EntryPoints/UserRolesV1Router.ts index 1fa1999..d06e497 100644 --- a/src/EntryPoints/UserRolesV1Router.ts +++ b/src/EntryPoints/UserRolesV1Router.ts @@ -1,10 +1,10 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { UserRole } from "@src/Domain/User/Entity/UserRole.js"; import { UserRoleFilter } from "@src/Domain/User/Entity/UserRoleFilter.js"; import type { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; @@ -125,7 +125,7 @@ export function createUserRolesRouter( const userRole: UserRole = new UserRole( userId, - Number.parseInt(roleId), + Number.parseInt(roleId, 10), ); const request = new RequestModel(transactionId, userRole); @@ -170,7 +170,7 @@ export function createUserRolesRouter( const userRole: UserRole = new UserRole( userId, - Number.parseInt(roleId), + Number.parseInt(roleId, 10), ); const request = new RequestModel(transactionId, userRole); diff --git a/src/EntryPoints/UsersV1Router.test.ts b/src/EntryPoints/UsersV1Router.test.ts index 56a7271..71261c1 100644 --- a/src/EntryPoints/UsersV1Router.test.ts +++ b/src/EntryPoints/UsersV1Router.test.ts @@ -1,19 +1,18 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { User } from "@src/Domain/User/Entity/User.js"; import { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; import { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; import { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express, { + type NextFunction, type Request, type Response, - type NextFunction, } from "express"; import supertest from "supertest"; -import { createUsersRouter } from "./UsersV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createUsersRouter } from "./UsersV1Router.js"; vi.mock("@src/Domain/User/UseCase/UserQueryUseCase"); vi.mock("@src/Domain/User/UseCase/UserPasswordUseCase"); diff --git a/src/EntryPoints/UsersV1Router.ts b/src/EntryPoints/UsersV1Router.ts index e9db7b4..60ee293 100644 --- a/src/EntryPoints/UsersV1Router.ts +++ b/src/EntryPoints/UsersV1Router.ts @@ -8,8 +8,8 @@ import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase import { hasPermissions } from "@variamosple/variamos-security"; import { type Request, Router } from "express"; import logger from "jet-logger"; -import { USER_ROLES_V1_ROUTE } from "./UserRolesV1Router.js"; import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; +import { USER_ROLES_V1_ROUTE } from "./UserRolesV1Router.js"; export const USERS_V1_ROUTE = "/v1/users"; diff --git a/src/EntryPoints/VisitsV1Router.test.ts b/src/EntryPoints/VisitsV1Router.test.ts index 74c6c94..2536472 100644 --- a/src/EntryPoints/VisitsV1Router.test.ts +++ b/src/EntryPoints/VisitsV1Router.test.ts @@ -1,13 +1,12 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; import { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import express from "express"; import supertest from "supertest"; -import { createVisitsRouter } from "./VisitsV1Router.js"; - import { mock } from "vitest-mock-extended"; +import { createVisitsRouter } from "./VisitsV1Router.js"; interface CustomRequest { user?: { id: string }; diff --git a/src/EntryPoints/VisitsV1Router.ts b/src/EntryPoints/VisitsV1Router.ts index fdbbb78..7d319f7 100644 --- a/src/EntryPoints/VisitsV1Router.ts +++ b/src/EntryPoints/VisitsV1Router.ts @@ -1,9 +1,9 @@ +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { RequestModel } from "@src/Domain/Core/Entity/RequestModel.js"; import { ResponseModel } from "@src/Domain/Core/Entity/ResponseModel.js"; import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { Visit } from "@src/Domain/Visit/Entity/Visit.js"; import type { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; import { isAuthenticated } from "@variamosple/variamos-security"; import { Router } from "express"; import logger from "jet-logger"; @@ -22,7 +22,7 @@ export function createVisitsRouter(visitUseCase: VisitUseCase): Router { (req.headers["x-forwarded-for"] as string) || req.ip; try { - if (!pageId || !user || !user.id) { + if (!pageId || !user?.id) { return res .status(HttpStatusCodes.BAD_REQUEST) .json( diff --git a/src/EntryPoints/errorMapper.test.ts b/src/EntryPoints/errorMapper.test.ts index 1872904..e8f83fd 100644 --- a/src/EntryPoints/errorMapper.test.ts +++ b/src/EntryPoints/errorMapper.test.ts @@ -1,5 +1,5 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import { mapDomainErrorToHttpStatus } from "./errorMapper.js"; describe("errorMapper Unit Tests", () => { diff --git a/src/EntryPoints/errorMapper.ts b/src/EntryPoints/errorMapper.ts index 0ab16c5..b2caad4 100644 --- a/src/EntryPoints/errorMapper.ts +++ b/src/EntryPoints/errorMapper.ts @@ -1,5 +1,5 @@ -import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { DomainErrorCodes } from "@src/Domain/Core/Error/DomainErrorCodes.js"; export function mapDomainErrorToHttpStatus( errorCode?: string | number | null, diff --git a/src/EntryPoints/index.ts b/src/EntryPoints/index.ts index 96b133f..94876fc 100644 --- a/src/EntryPoints/index.ts +++ b/src/EntryPoints/index.ts @@ -1,10 +1,35 @@ import EnvVars from "@src/common/EnvVars.js"; +import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; +import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; +import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js"; +// Bug Flow Use Cases +import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; +import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; +import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; +// Other Use Cases +import type { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; +import type { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; +import type { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; +import type { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; +// Role & Permission Use Cases +import type { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; +import type { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; +import type { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; + +// User Flow Use Cases +import type { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; +import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; +import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; +import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; +import type { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; +import type { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; +import { isAuthenticated } from "@variamosple/variamos-security"; import { Router } from "express"; import { AUTH_ROUTE, createAuthRouter } from "./AuthRouter.js"; import { BUG_V1_ROUTE, - type MulterUpload, createBugRouter, + type MulterUpload, } from "./BugRouter.js"; import { CONFIGURATION_V1_ROUTE, @@ -14,49 +39,20 @@ import { COUNTRIES_V1_ROUTE, createCountriesRouter, } from "./CountriesV1Router.js"; -import { METRICS_V1_ROUTE, createMetricsRouter } from "./MetricsV1Router.js"; +import { createMetricsRouter, METRICS_V1_ROUTE } from "./MetricsV1Router.js"; import { - MICRO_SERVICES_V1_ROUTE, createMicroServicesRouter, + MICRO_SERVICES_V1_ROUTE, } from "./MicroServicesV1Router.js"; import { - PERMISSIONS_V1_ROUTE, createPermissionsRouter, + PERMISSIONS_V1_ROUTE, } from "./PermissionsV1Router.js"; import { createRolePermissionsRouter } from "./RolePermissionsV1Router.js"; -import { ROLES_V1_ROUTE, createRolesRouter } from "./RolesV1Router.js"; +import { createRolesRouter, ROLES_V1_ROUTE } from "./RolesV1Router.js"; import { createUserRolesRouter } from "./UserRolesV1Router.js"; -import { USERS_V1_ROUTE, createUsersRouter } from "./UsersV1Router.js"; -import { VISITS_V1_ROUTE, createVisitsRouter } from "./VisitsV1Router.js"; - -// User Flow Use Cases -import type { UserAuthUseCase } from "@src/Domain/User/UseCase/UserAuthUseCase.js"; -import type { UserManagementUseCase } from "@src/Domain/User/UseCase/UserManagementUseCase.js"; -import type { UserPasswordUseCase } from "@src/Domain/User/UseCase/UserPasswordUseCase.js"; -import type { UserQueryUseCase } from "@src/Domain/User/UseCase/UserQueryUseCase.js"; -import type { UserRoleUseCase } from "@src/Domain/User/UseCase/UserRoleUseCase.js"; - -import type { BugAttachmentUseCase } from "@src/Domain/Bug/UseCase/BugAttachmentUseCase.js"; -import type { BugLifecycleUseCase } from "@src/Domain/Bug/UseCase/BugLifecycleUseCase.js"; -import type { BugQueryUseCase } from "@src/Domain/Bug/UseCase/BugQueryUseCase.js"; -// Bug Flow Use Cases -import type { BugSubmissionUseCase } from "@src/Domain/Bug/UseCase/BugSubmissionUseCase.js"; -import type { BugSyncUseCase } from "@src/Domain/Bug/UseCase/BugSyncUseCase.js"; - -import type { PermissionUseCase } from "@src/Domain/Permission/UseCase/PermissionUseCase.js"; -// Role & Permission Use Cases -import type { RoleManagementUseCase } from "@src/Domain/Role/UseCase/RoleManagementUseCase.js"; -import type { RolePermissionUseCase } from "@src/Domain/Role/UseCase/RolePermissionUseCase.js"; -import type { RoleQueryUseCase } from "@src/Domain/Role/UseCase/RoleQueryUseCase.js"; - -import type { CountriesQueryUseCase } from "@src/Domain/Countries/UseCase/CountriesQueryUseCase.js"; -// Other Use Cases -import type { MetricsQueryUseCase } from "@src/Domain/Metrics/UseCase/MetricsQueryUseCase.js"; -import type { MicroServiceManagementUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceManagementUseCase.js"; -import type { MicroServiceQueryUseCase } from "@src/Domain/MicroService/UseCase/MicroServiceQueryUseCase.js"; -import type { VisitUseCase } from "@src/Domain/Visit/UseCase/VisitUseCase.js"; - -import { isAuthenticated } from "@variamosple/variamos-security"; +import { createUsersRouter, USERS_V1_ROUTE } from "./UsersV1Router.js"; +import { createVisitsRouter, VISITS_V1_ROUTE } from "./VisitsV1Router.js"; export interface UserFlowUseCases { auth: UserAuthUseCase; diff --git a/src/Infrastructure/Mail/MailService.ts b/src/Infrastructure/Mail/MailService.ts index 7f21f2e..d0471e2 100644 --- a/src/Infrastructure/Mail/MailService.ts +++ b/src/Infrastructure/Mail/MailService.ts @@ -1,5 +1,5 @@ -import type { IMailService } from "@src/Domain/Mail/IMailService.js"; import EnvVars from "@src/common/EnvVars.js"; +import type { IMailService } from "@src/Domain/Mail/IMailService.js"; import logger from "jet-logger"; /* cspell:disable */ import nodemailer from "nodemailer"; diff --git a/src/common/EnvVars.ts b/src/common/EnvVars.ts index 502e748..ac18746 100644 --- a/src/common/EnvVars.ts +++ b/src/common/EnvVars.ts @@ -3,8 +3,6 @@ * Environments variables declared here. */ -/* eslint-disable node/no-process-env */ - export default { NodeEnv: process.env.NODE_ENV ?? "", Port: process.env.PORT ?? 0, diff --git a/src/index.ts b/src/index.ts index 25023d9..7a19e83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,10 +7,6 @@ import EnvVars from "@src/common/EnvVars.js"; import { initKeyStore, validateSession } from "@variamosple/variamos-security"; import { parseCookie } from "cookie"; import { WebSocket, WebSocketServer } from "ws"; -import { RequestModel } from "./Domain/Core/Entity/RequestModel.js"; -import { createBaseRouter } from "./EntryPoints/index.js"; -import { createServer } from "./server.js"; - import { productionBugAttachmentUseCase, productionBugLifecycleUseCase, @@ -32,10 +28,12 @@ import { productionUserRoleUseCase, productionVisitUseCase, } from "./CompositionRoot.js"; - import { BugModel } from "./DataProviders/Bug/Bug.js"; import { BugAttachmentModel } from "./DataProviders/Bug/BugAttachment.js"; import { BugLogModel } from "./DataProviders/Bug/BugLog.js"; +import { RequestModel } from "./Domain/Core/Entity/RequestModel.js"; +import { createBaseRouter } from "./EntryPoints/index.js"; +import { createServer } from "./server.js"; import "./DataProviders/Bug/BugAssociations.js"; import fs from "node:fs"; diff --git a/src/server.ts b/src/server.ts index d21a594..84f08c7 100644 --- a/src/server.ts +++ b/src/server.ts @@ -3,6 +3,10 @@ */ import path from "node:path"; +import { RouteError } from "@src/common/classes.js"; +import EnvVars from "@src/common/EnvVars.js"; +import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; +import { NodeEnvs } from "@src/common/misc.js"; import cookieParser from "cookie-parser"; import cors from "cors"; import express, { @@ -15,11 +19,6 @@ import helmet from "helmet"; import logger from "jet-logger"; import morgan from "morgan"; -import EnvVars from "@src/common/EnvVars.js"; -import HttpStatusCodes from "@src/common/HttpStatusCodes.js"; -import { RouteError } from "@src/common/classes.js"; -import { NodeEnvs } from "@src/common/misc.js"; - export function createServer(baseRouter: Router) { const app = express(); @@ -67,24 +66,16 @@ export function createServer(baseRouter: Router) { app.use("/", baseRouter); // Add error handler - app.use( - ( - err: Error, - _: Request, - res: Response, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _next: NextFunction, - ) => { - if (EnvVars.NodeEnv !== NodeEnvs.Test.valueOf()) { - logger.err(err, true); - } - let status = HttpStatusCodes.BAD_REQUEST; - if (err instanceof RouteError) { - status = err.status; - } - return res.status(status).json({ error: err.message }); - }, - ); + app.use((err: Error, _: Request, res: Response, _next: NextFunction) => { + if (EnvVars.NodeEnv !== NodeEnvs.Test.valueOf()) { + logger.err(err, true); + } + let status = HttpStatusCodes.BAD_REQUEST; + if (err instanceof RouteError) { + status = err.status; + } + return res.status(status).json({ error: err.message }); + }); // **** Front-End Content **** // diff --git a/tsconfig.json b/tsconfig.json index 1106027..5df845a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ "outDir": "dist", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ @@ -42,7 +42,6 @@ /* Module Resolution Options */ "moduleResolution": "node16", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ @@ -67,17 +66,18 @@ "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ "paths": { "@src/*": [ - "src/*" + "./src/*" ], }, - "useUnknownInCatchVariables": false + "useUnknownInCatchVariables": false, + "types": ["vitest/globals"] }, "include": [ "src/**/*.ts", "spec/**/*.ts", "build.ts", - "jest.config.ts", - "jest.setup.ts" + "vitest.config.ts", + "vitest.setup.ts" ], "exclude": [ "src/public/" diff --git a/vitest.config.ts b/vitest.config.ts index 27d4dd7..3ec097e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from "vitest/config"; +import { defineConfig, configDefaults } from "vitest/config"; import tsconfigPaths from "vite-tsconfig-paths"; import * as dotenv from "dotenv"; import * as path from "path"; @@ -12,6 +12,7 @@ export default defineConfig({ globals: true, environment: "node", setupFiles: ["./vitest.setup.ts"], + exclude: [...configDefaults.exclude, "**/dist/**", "**/.stryker-tmp/**"], coverage: { provider: "v8", include: ["src/Domain/**/*.ts", "src/EntryPoints/**/*.ts"], diff --git a/vitest.setup.ts b/vitest.setup.ts index 439861d..f6c12e5 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -1,8 +1,12 @@ import { vi, afterAll } from "vitest"; import VARIAMOS_ORM from "./src/Infrastructure/VariamosORM.js"; - -// Set global jest object to map to Vitest's vi to support all existing test code without rewriting it -(globalThis as any).jest = vi; +declare global { + namespace vi { + type Mock any = (...args: any[]) => any> = import("vitest").Mock; + type Mocked = import("vitest").Mocked; + type SpyInstance any = (...args: any[]) => any> = import("vitest").MockInstance; + } +} // Silence console logs and errors during test executions to keep output clean vi.spyOn(console, "log").mockImplementation(() => {});