diff --git a/package-lock.json b/package-lock.json index d8b22647c..f3c0cf75e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,141 +6,23 @@ "": { "hasInstallScript": true, "license": "ComtyLicense", - "dependencies": { - "react-virtualized": "^9.22.6" + "devDependencies": { + "typescript": "^6.0.3" } }, - "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, + "node_modules/typescript": { + "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": { - "loose-envify": "cli.js" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "scheduler": "^0.27.0" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, - "peerDependencies": { - "react": "^19.2.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "license": "MIT" - }, - "node_modules/react-virtualized": { - "version": "9.22.6", - "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.6.tgz", - "integrity": "sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.7.2", - "clsx": "^1.0.4", - "dom-helpers": "^5.1.3", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": ">=14.17" } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT", - "peer": true } } } diff --git a/package.json b/package.json index 1336d4e43..6dec61e8e 100755 --- a/package.json +++ b/package.json @@ -10,5 +10,8 @@ "setup:server": "cd packages/server && npm run setup", "postinstall": "cd packages/app && npm install && cd ../server && npm install" }, - "_web_app_path": "packages/app" + "_web_app_path": "packages/app", + "devDependencies": { + "typescript": "^6.0.3" + } } diff --git a/packages/app/config/defaultSettings.json b/packages/app/config/defaultSettings.json index 2c247a70c..870cabdf2 100755 --- a/packages/app/config/defaultSettings.json +++ b/packages/app/config/defaultSettings.json @@ -20,6 +20,8 @@ "mediartc:soundpad:volume": 0.2, "mediartc:noiseSuppression": "native", + "mediartc:inputGain": 1, + "mediartc:outputGain": 1, "mediartc:autoGain": false, "mediartc:echoCancellation": true } diff --git a/packages/app/package-lock.json b/packages/app/package-lock.json index f4e670b12..d6342fd3b 100644 --- a/packages/app/package-lock.json +++ b/packages/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "@comty/app", - "version": "2.13.0@alpha", + "version": "2.14.0@alpha", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@comty/app", - "version": "2.13.0@alpha", + "version": "2.14.0@alpha", "hasInstallScript": true, "license": "ComtyLicense", "dependencies": { @@ -21,6 +21,9 @@ "@ffmpeg/util": "^0.12.1", "@gullerya/object-observer": "^6.1.4", "@loadable/component": "^5.16.7", + "@preact/preset-vite": "^2.10.5", + "@preact/signals": "^2.9.0", + "@preact/signals-react": "^3.10.0", "@ragestudio/vessel": "^0.25.7", "@sentry/browser": "^7.64.0", "@svta/common-media-library": "^0.18.1", @@ -35,6 +38,8 @@ "d3": "^7.9.0", "dashjs": "^5.0.3", "dayjs": "^1.11.19", + "dexie": "^4.3.0", + "dexie-react-hooks": "^4.2.0", "dompurify": "^3.3.2", "fast-average-color": "^9.2.0", "file-type": "^21.3.3", @@ -58,6 +63,7 @@ "music-metadata": "^11.12.3", "ogl": "^1.0.11", "plyr": "^3.7.8", + "preact": "^10.29.0", "prop-types": "^15.8.1", "react": "^19.2.4", "react-color": "2.19.3", @@ -66,7 +72,7 @@ "react-fast-marquee": "^1.3.5", "react-i18next": "11.15.3", "react-icons": "^5.4.0", - "react-intersection-observer": "^9.16.0", + "react-intersection-observer": "^10.0.3", "react-lazy-load-image-component": "^1.5.4", "react-markdown": "^8.0.3", "react-player": "^2.16.1", @@ -81,7 +87,8 @@ "store": "^2.0.12", "ua-parser-js": "^1.0.36", "vaul": "^1.1.2", - "vite": "^7.3.1" + "vite": "^7.3.1", + "xxhash-wasm": "^1.1.0" }, "devDependencies": { "@eslint/js": "^9.26.0", @@ -202,12 +209,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -262,21 +269,33 @@ "license": "MIT" }, "node_modules/@babel/generator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", - "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.5", - "@babel/types": "^7.27.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", @@ -293,14 +312,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -324,9 +352,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -342,9 +370,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -373,12 +401,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -387,6 +415,55 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz", + "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-jsx": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", @@ -427,54 +504,45 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1380,17 +1448,13 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "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==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1402,15 +1466,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "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", @@ -1418,9 +1473,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1464,6 +1519,44 @@ "node": ">=14" } }, + "node_modules/@preact/preset-vite": { + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.10.5.tgz", + "integrity": "sha512-p0vJpxiVO7KWWazWny3LUZ+saXyZKWv6Ju0bYMWNJRp2YveufRPgSUB1C4MTqGJfz07EehMgfN+AJNwQy+w6Iw==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@prefresh/vite": "^2.4.11", + "@rollup/pluginutils": "^5.0.0", + "babel-plugin-transform-hook-names": "^1.0.2", + "debug": "^4.4.3", + "magic-string": "^0.30.21", + "picocolors": "^1.1.1", + "vite-prerender-plugin": "^0.5.8", + "zimmerframe": "^1.1.4" + }, + "peerDependencies": { + "@babel/core": "7.x", + "vite": "2.x || 3.x || 4.x || 5.x || 6.x || 7.x || 8.x" + } + }, + "node_modules/@preact/signals": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-2.9.0.tgz", + "integrity": "sha512-hYrY0KyUqkDgOl1qba/JGn6y81pXnurn21PMaxfcMwdncdZ3M/oVdmpTvEnsGjh48dIwDVc7bjWHqIsngSjYug==", + "license": "MIT", + "dependencies": { + "@preact/signals-core": "^1.14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "preact": ">= 10.25.0 || >=11.0.0-0" + } + }, "node_modules/@preact/signals-core": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.0.tgz", @@ -1474,6 +1567,86 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/@preact/signals-react": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@preact/signals-react/-/signals-react-3.10.0.tgz", + "integrity": "sha512-Uxu6lidNVr9z27b/6DbCin86ekzHiJDrLXZii82aXSzvyMXYMr7l0Bab1cKbfWdbkxq13e7kS7paix3pjKBTLA==", + "license": "MIT", + "dependencies": { + "@preact/signals-core": "^1.14.0", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, + "node_modules/@prefresh/babel-plugin": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@prefresh/babel-plugin/-/babel-plugin-0.5.3.tgz", + "integrity": "sha512-57LX2SHs4BX2s1IwCjNzTE2OJeEepRCNf1VTEpbNcUyHfMO68eeOWGDIt4ob9aYlW6PEWZ1SuwNikuoIXANDtQ==", + "license": "MIT" + }, + "node_modules/@prefresh/core": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/@prefresh/core/-/core-1.5.9.tgz", + "integrity": "sha512-IKBKCPaz34OFVC+adiQ2qaTF5qdztO2/4ZPf4KsRTgjKosWqxVXmEbxCiUydYZRY8GVie+DQlKzQr9gt6HQ+EQ==", + "license": "MIT", + "peerDependencies": { + "preact": "^10.0.0 || ^11.0.0-0" + } + }, + "node_modules/@prefresh/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@prefresh/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==", + "license": "MIT" + }, + "node_modules/@prefresh/vite": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@prefresh/vite/-/vite-2.4.12.tgz", + "integrity": "sha512-FY1fzXpUjiuosznMV0YM7XAOPZjB5FIdWS0W24+XnlxYkt9hNAwwsiKYn+cuTEoMtD/ZVazS5QVssBr9YhpCQA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.22.1", + "@prefresh/babel-plugin": "^0.5.2", + "@prefresh/core": "^1.5.0", + "@prefresh/utils": "^1.2.0", + "@rollup/pluginutils": "^4.2.1" + }, + "peerDependencies": { + "preact": "^10.4.0 || ^11.0.0-0", + "vite": ">=2.0.0" + } + }, + "node_modules/@prefresh/vite/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@prefresh/vite/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==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", @@ -4001,6 +4174,15 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/babel-plugin-transform-hook-names": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz", + "integrity": "sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==", + "license": "MIT", + "peerDependencies": { + "@babel/core": "^7.12.10" + } + }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -4057,6 +4239,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -4397,6 +4585,34 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -5031,6 +5247,24 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, + "node_modules/dexie": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/dexie/-/dexie-4.3.0.tgz", + "integrity": "sha512-5EeoQpJvMKHe6zWt/FSIIuRa3CWlZeIl6zKXt+Lz7BU6RoRRLgX9dZEynRfXrkLcldKYCBiz7xekTEylnie1Ug==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/dexie-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dexie-react-hooks/-/dexie-react-hooks-4.2.0.tgz", + "integrity": "sha512-u7KqTX9JpBQK8+tEyA9X0yMGXlSCsbm5AU64N6gjvGk/IutYDpLBInMYEAEC83s3qhIvryFS+W+sqLZUBEvePQ==", + "license": "Apache-2.0", + "peerDependencies": { + "@types/react": ">=16", + "dexie": ">=4.2.0-alpha.1 <5.0.0", + "react": ">=16" + } + }, "node_modules/diff": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", @@ -5063,6 +5297,47 @@ "csstype": "^3.0.2" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, "node_modules/dompurify": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", @@ -5075,6 +5350,20 @@ "@types/trusted-types": "^2.0.7" } }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5116,6 +5405,18 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -6181,6 +6482,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/hls.js": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.5.tgz", @@ -7106,6 +7416,12 @@ "node": ">=6" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT" + }, "node_modules/less": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/less/-/less-4.3.0.tgz", @@ -7389,6 +7705,15 @@ "node": ">=12" } }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -8559,12 +8884,34 @@ } } }, + "node_modules/node-html-parser": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz", + "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==", + "license": "MIT", + "dependencies": { + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8931,6 +9278,17 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/preact": { + "version": "10.29.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.0.tgz", + "integrity": "sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -9146,9 +9504,9 @@ } }, "node_modules/react-intersection-observer": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz", - "integrity": "sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-10.0.3.tgz", + "integrity": "sha512-luICLMbs0zxTO/70Zy7K5jOXkABPEVSAF8T3FdZUlctsrIaPLmx8TZe2SSA+CY2HGWfz2INyNTnp82pxNNsShA==", "license": "MIT", "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0", @@ -9892,6 +10250,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-code-frame": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/simple-code-frame/-/simple-code-frame-1.3.0.tgz", + "integrity": "sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==", + "license": "MIT", + "dependencies": { + "kolorist": "^1.6.0" + } + }, + "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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -9911,6 +10287,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/stack-trace": { + "version": "1.0.0-pre2", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz", + "integrity": "sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -10753,6 +11138,15 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/uuid": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", @@ -10902,6 +11296,23 @@ } } }, + "node_modules/vite-prerender-plugin": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/vite-prerender-plugin/-/vite-prerender-plugin-0.5.13.tgz", + "integrity": "sha512-IKSpYkzDBsKAxa05naRbj7GvNVMSdww/Z/E89oO3xndz+gWnOBOKOAbEXv7qDhktY/j3vHgJmoV1pPzqU2tx9g==", + "license": "MIT", + "dependencies": { + "kolorist": "^1.8.0", + "magic-string": "0.x >= 0.26.0", + "node-html-parser": "^6.1.12", + "simple-code-frame": "^1.3.0", + "source-map": "^0.7.4", + "stack-trace": "^1.0.0-pre2" + }, + "peerDependencies": { + "vite": "5.x || 6.x || 7.x || 8.x" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -11141,6 +11552,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -11160,6 +11577,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT" + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/packages/app/package.json b/packages/app/package.json index 17997f461..1417089c2 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -26,6 +26,7 @@ "@ffmpeg/util": "^0.12.1", "@gullerya/object-observer": "^6.1.4", "@loadable/component": "^5.16.7", + "@preact/signals-react": "^3.10.0", "@ragestudio/vessel": "^0.25.7", "@sentry/browser": "^7.64.0", "@svta/common-media-library": "^0.18.1", @@ -40,6 +41,8 @@ "d3": "^7.9.0", "dashjs": "^5.0.3", "dayjs": "^1.11.19", + "dexie": "^4.3.0", + "dexie-react-hooks": "^4.2.0", "dompurify": "^3.3.2", "fast-average-color": "^9.2.0", "file-type": "^21.3.3", @@ -71,7 +74,7 @@ "react-fast-marquee": "^1.3.5", "react-i18next": "11.15.3", "react-icons": "^5.4.0", - "react-intersection-observer": "^9.16.0", + "react-intersection-observer": "^10.0.3", "react-lazy-load-image-component": "^1.5.4", "react-markdown": "^8.0.3", "react-player": "^2.16.1", diff --git a/packages/app/public/docs/comty-spaces-tos.md b/packages/app/public/docs/comty-spaces-tos.md new file mode 100644 index 000000000..57b897889 --- /dev/null +++ b/packages/app/public/docs/comty-spaces-tos.md @@ -0,0 +1,65 @@ +## Welcome to Comty Spaces. +These terms extend the [Comty General Terms of Service]. +By using these experimental features—including public/private groups, Direct Messages (DMs), and real-time audio/video—you agree to the following conditions. + +### 1. Service Integrity & Data Volatility +Comty Spaces is currently in active development. Because we are still building the foundation, the following applies: + +***Development Phase Risks***: During this experimental period, data such as message history, group memberships, and settings may be lost, corrupted, or reset due to database migrations or technical errors. + +***Transition to Stability***: These volatility risks are a product of the current development stage. Once Comty Spaces reaches a "Stable" or "General Release" status, we will implement standard data redundancy and uptime guarantees. + +***No Production Guarantee***: For now, do not use Spaces for critical communication or as your only storage for important information. Comty Spaces is not liable for data loss occurring during this beta phase. + +### 2. Direct Messages (DMs) +DMs are private conversations between you and other users. To keep them safe and functional: + +***User Responsibility***: You are responsible for the conversations you start and the people you interact with. Comty Spaces may provides "Block" and "Mute" tools—please use them. + +***Privacy Expectations***: We do not monitor your private conversations. However, if a participant in a DM reports a conversation for a violation of our Code of Conduct, our safety team may review the reported logs to take necessary action. + +***No Spam***: Using DMs to mass-distribute unsolicited links, advertisements, or "scam" content is strictly prohibited and will result in an immediate ban. + +### 3. Code of Conduct (CoC) +All users, whether in public groups or private DMs, must follow these core rules: + +***Safety & Legality***: No promotion of self-harm, violence, or illegal activities. + +***Zero Tolerance for Harassment***: No bullying, doxxing, or hate speech. + +***Media Consent***: Do not record or distribute audio/video calls without the explicit consent of all participants. + +***System Integrity***: Do not use the service to distribute malware or attempt to degrade platform performance. + +### 4. Public Groups & Moderation +If you own or manage a Public Group: + +***Your House, Your Rules***: You are the primary moderator. You are expected to enforce both your own community rules and this Code of Conduct. + +***Reporting***: Use built-in tools to flag content. Comty reserves the right to remove content or dissolve Groups that systematically violate legal requirements or our core safety policies. + +### 5. Technical Limits & Bitrate +To keep the experimental infrastructure running smoothly: + +***Bandwidth***: We enforce caps on audio/video bitrates. Attempting to bypass these via modified clients or scripts is a violation of these terms. + +***Rate Limiting***: Automated scripts or bots must respect our API and rate-limiting thresholds to prevent server strain. + +### 6. GDPR & Data Rights +We remain fully committed to the EU General Data Protection Regulation (GDPR): + +Processing: We process your metadata and content solely to facilitate your communications. + +Your Rights: You retain the right to access or delete your data. Note that while we fulfill deletion requests promptly, some data may remain in encrypted backups for a short period until the next rotation. + +### 7. Intellectual Property & DMCA +***Content Ownership***: You own what you post. By using Spaces, you grant us the technical license needed to transmit and display that content to your intended recipients. + +***Copyright***: We comply with the DMCA. If you repeatedly share copyrighted material without permission, your access to Spaces will be revoked. + +### 8. Termination +We reserve the right to suspend or terminate your access to Comty Spaces if you violate these terms. In cases of severe technical abuse or harassment, this may extend to your entire Comty account. + +TL;DR: We’re still building this, so expect some technical hiccups and potential data resets until we hit "Stable" status. Be respectful in DMs and public groups, don't hack the bitrate, and we’ll all have a good time. + +By continuing to use Comty Spaces, you acknowledge that you understand the experimental nature of the service and agree to the Code of Conduct. diff --git a/packages/app/src/components/MarkdownReader/index.jsx b/packages/app/src/components/MarkdownReader/index.jsx index 48784dfc8..0aaba8650 100755 --- a/packages/app/src/components/MarkdownReader/index.jsx +++ b/packages/app/src/components/MarkdownReader/index.jsx @@ -1,42 +1,38 @@ -import React from "react" +import { Result, Skeleton } from "antd" import ReactMarkdown from "react-markdown" import remarkGfm from "remark-gfm" -import { - Result, - Skeleton -} from "antd" +import use from "comty.js/hooks/use" import "./index.less" -export default (props) => { - const [L_Doc, R_Doc, E_Doc] = app.cores.api.useRequest(async () => { - const response = await app.cores.api.customRequest({ - method: "GET", - url: props.url, - }) +const fetchText = async (url, args) => { + return await (await fetch(url, args)).text() +} - return response.data - }) +const MarkdownReader = (props) => { + const { loading, result, error } = use(fetchText, props.url, { + method: "GET", + }) - React.useEffect(() => { - app.layout.toggleCenteredContent(true) - }, []) + if (error) { + return ( + + ) + } - if (E_Doc) { - return - } + if (loading) { + return + } - if (L_Doc) { - return - } + return ( +
+ {result} +
+ ) +} - return
- - {R_Doc} - -
-} \ No newline at end of file +export default MarkdownReader diff --git a/packages/app/src/components/MarkdownReader/index.less b/packages/app/src/components/MarkdownReader/index.less index 03e8a7cc5..17c1ea28e 100755 --- a/packages/app/src/components/MarkdownReader/index.less +++ b/packages/app/src/components/MarkdownReader/index.less @@ -1,58 +1,60 @@ .document_viewer { - display: flex; - flex-direction: column; - - align-items: start; - justify-content: start; - - text-align: start; - - >* { - user-select: text; - } - - - blockquote { - background-color: var(--background-color-accent); - border-radius: 8px; - padding: 7px; - } - - h2, - h3, - h4, - h5, - h6 { - margin-top: 10px; - margin-bottom: 5px; - } - - span, - p, - a { - margin: 5px; - } - - ul { - color: var(--text-color); - } - - ol { - color: var(--text-color); - } - - li { - color: var(--text-color); - } - - table { - color: var(--text-color); - margin: 20px 10px; - - - td { - padding: 7px; - outline: 1px solid var(--border-color); - } - } -} \ No newline at end of file + display: flex; + flex-direction: column; + + align-items: start; + justify-content: start; + + text-align: start; + + height: 100%; + + padding-bottom: 10px; + + > * { + user-select: text; + } + + blockquote { + background-color: var(--background-color-accent); + border-radius: 8px; + padding: 7px; + } + + h2, + h3, + h4, + h5, + h6 { + margin-top: 10px; + margin-bottom: 5px; + } + + span, + p, + a { + margin: 5px; + } + + ul { + color: var(--text-color); + } + + ol { + color: var(--text-color); + } + + li { + color: var(--text-color); + } + + table { + color: var(--text-color); + margin: 20px 10px; + + td { + padding: 7px; + outline: 1px solid var(--border-color); + } + } +} diff --git a/packages/app/src/components/Spaces/Chat/components/GifPicker.jsx b/packages/app/src/components/Spaces/Chat/components/GifPicker.jsx new file mode 100644 index 000000000..c34b673a0 --- /dev/null +++ b/packages/app/src/components/Spaces/Chat/components/GifPicker.jsx @@ -0,0 +1,31 @@ +import React from "react" +import Icons from "@components/Icons" +import Button from "@ui/Button" +import Popover from "@ui/Popover" +import { Skeleton } from "antd" + +import "./GifPicker.less" + +const GifPickerDialog = () => { + return
+} + +const GifPicker = ({ onClickItem }) => { + return ( + ( + + )} + className="emoji-picker-popover" + > + + + ) +} +export default GifPicker diff --git a/packages/app/src/components/Spaces/Chat/components/GifPicker.less b/packages/app/src/components/Spaces/Chat/components/GifPicker.less new file mode 100644 index 000000000..17684323f --- /dev/null +++ b/packages/app/src/components/Spaces/Chat/components/GifPicker.less @@ -0,0 +1,2 @@ +.gif-picker { +} diff --git a/packages/app/src/components/Spaces/Chat/components/InputBar.jsx b/packages/app/src/components/Spaces/Chat/components/InputBar.jsx index c97fbd3b1..d465f7f66 100644 --- a/packages/app/src/components/Spaces/Chat/components/InputBar.jsx +++ b/packages/app/src/components/Spaces/Chat/components/InputBar.jsx @@ -8,9 +8,11 @@ import useOnPaste from "@hooks/useOnPaste" import UploadAttachments from "./UploadAttachments" -import "./InputBar.less" import StickersButton from "./StickersButton" import EmojiPicker from "./EmojiPicker" +import GifPicker from "./GifPicker" + +import "./InputBar.less" const ChatInputBar = React.memo(({ channel_id, send, typing }) => { const [inputValue, setInputValue] = React.useState("") @@ -94,7 +96,11 @@ const ChatInputBar = React.memo(({ channel_id, send, typing }) => { // update the file prev[index].url = response.url - prev[index].hash = response.metadata["File-Hash"] + + if (response.metadata) { + prev[index].hash = response.metadata?.["File-Hash"] + } + prev[index].pending = false return prev @@ -152,6 +158,11 @@ const ChatInputBar = React.memo(({ channel_id, send, typing }) => { sendSticker(sticker)} /> + { + console.log(gifUrl) + }} + /> ) }, @@ -87,10 +95,12 @@ const RenderMessage = ({ messageStr }) => { } const Line = React.memo(({ data, headless }) => { + const userData = useLiveQuery(() => db.users.get(data.user_id)) + return (
{ {!headless && (
{data.user.username}
)} @@ -110,11 +120,11 @@ const Line = React.memo(({ data, headless }) => {
- {data.user?.public_name ?? - `@${data.user?.username}`} + {userData?.public_name ?? + `@${userData?.username}`} - {data.user.bot && ( + {userData?.bot && (
Bot
diff --git a/packages/app/src/components/Spaces/Chat/components/UploadAttachments.jsx b/packages/app/src/components/Spaces/Chat/components/UploadAttachments.jsx index a319f7e42..0566a37c9 100644 --- a/packages/app/src/components/Spaces/Chat/components/UploadAttachments.jsx +++ b/packages/app/src/components/Spaces/Chat/components/UploadAttachments.jsx @@ -2,15 +2,20 @@ import classNames from "classnames" import AttachmentMedia from "./UploadAttachment" +import "./UploadAttachments.less" + const Attachments = ({ items }) => { return ( -
+
{items.map((item) => (
diff --git a/packages/app/src/components/Spaces/Chat/components/UploadAttachments.less b/packages/app/src/components/Spaces/Chat/components/UploadAttachments.less new file mode 100644 index 000000000..ccffc9eb9 --- /dev/null +++ b/packages/app/src/components/Spaces/Chat/components/UploadAttachments.less @@ -0,0 +1,57 @@ +@chat-input-attachment-size: 120px; + +.channel-chat__input__attachments { + position: relative; + + display: flex; + flex-direction: row; + + align-items: center; + + width: 100%; + height: fit-content; + + gap: 10px; + padding: 10px; + + border-radius: 12px; + background-color: var(--background-color-accent); + /* + overflow-y: hidden; + overflow-x: scroll; */ + + scrollbar-gutter: stable; + + &__item { + overflow: hidden; + + position: relative; + + display: flex; + flex-direction: column; + + width: @chat-input-attachment-size; + height: @chat-input-attachment-size; + + min-width: @chat-input-attachment-size; + min-height: @chat-input-attachment-size; + + max-width: @chat-input-attachment-size; + max-height: @chat-input-attachment-size; + + background-color: var(--background-color-accent); + border-radius: 12px; + + &.pending { + filter: blur(2px); + opacity: 0.8; + } + + img { + width: 100%; + height: 100%; + + object-fit: cover; + } + } +} diff --git a/packages/app/src/components/Spaces/Chat/index.jsx b/packages/app/src/components/Spaces/Chat/index.jsx index 9c0db99ed..1da4aaf92 100644 --- a/packages/app/src/components/Spaces/Chat/index.jsx +++ b/packages/app/src/components/Spaces/Chat/index.jsx @@ -1,17 +1,16 @@ import React from "react" -import { Skeleton } from "antd" -import Button from "@ui/Button" +import { Result, Skeleton } from "antd" import { DateTime } from "luxon" +import { AnimatePresence, motion } from "motion/react" import PropTypes from "prop-types" -import { useInView } from "react-intersection-observer" - -import useChannelChat from "comty.js/hooks/useChannelChat" -import useDMChat from "comty.js/hooks/useDMChat" +import { useOnInView } from "react-intersection-observer" -import { useContentPanelHeaderRender } from "@contexts/WithSpaces/contentPanel" - -import Line from "./components/Line" +import Icons from "@components/Icons" +import Button from "@ui/Button" import ChatInputBar from "./components/InputBar" +import Line from "./components/Line" + +import useChat from "@contexts/WithSpaces/chat" import "./index.less" @@ -21,7 +20,7 @@ function shouldMergeWithNextItem(nextItem, item) { return false } - if (nextItem.user.username !== item.user.username) { + if (nextItem.user_id !== item.user_id) { return false } @@ -37,11 +36,41 @@ function shouldMergeWithNextItem(nextItem, item) { return true } -const Chat = ({ type = "group", _id, group = {} }) => { - if (!_id) { +const useTriggerValue = (callback) => { + const prevValueRef = React.useRef(false) + + return (value) => { + if (value === true && prevValueRef.current === false) { + callback() + } + + prevValueRef.current = value + } +} + +const Chat = ({ _id, type = "group", group }) => { + let useChatParam = {} + + if (!_id || !type) { + return null + } + + if (type === "group" && !group) { + console.error("Chat with type group, must provide a group context") return null } + if (type === "group") { + useChatParam = { group_id: group.data._id, channel_id: _id } + } + + if (type === "dm") { + useChatParam = { to_user_id: _id } + } + + const timelineRef = React.useRef() + const [scrollableToBottom, setScrollableToBottom] = React.useState(false) + const { timeline, loading, @@ -54,107 +83,58 @@ const Chat = ({ type = "group", _id, group = {} }) => { initialLoading, pausedUpdate, setPausedUpdates, - } = - type === "group" - ? useChannelChat(group._id, _id, { - onNewMessage: () => handleOnNewMessage(), - }) - : useDMChat(_id, { - onNewMessage: () => handleOnNewMessage(), - }) + } = useChat(type, useChatParam, { + onNewMessage: () => handleOnNewMessage(), + }) - const topTriggerInView = useInView() + const bottomTrigger = useTriggerValue(() => { + console.debug("View is BOTTOM, loading lasts messages") + loadAfter() + }) - const timelineRef = React.useRef() - const canLoadBottom = React.useRef(false) - const canLoadTop = React.useRef(true) + const topTrigger = useTriggerValue(() => { + console.debug("View is TOP, loading older messages") + loadBefore() + }) - const [scrollableToBottom, setScrollableToBottom] = React.useState(false) + const topTriggerRef = useOnInView((inView) => topTrigger(inView)) - const handleOnNewMessage = async () => { - if ( - timelineRef.current.scrollTop >= -100 && - timelineRef.current.scrollTop <= 0 - ) { - console.debug("scrolling to new messages") + const goToBottom = React.useCallback(() => { + if (timelineRef.current) { timelineRef.current.scrollTo(0, 0) } - } - - const handleOnScroll = React.useCallback( - (e) => { - const scrollPosition = Math.abs(timelineRef.current.scrollTop) - - const isScrollBottomInRange = - scrollPosition >= 0 && scrollPosition < 100 + }, [timelineRef]) - if (!loading && canLoadBottom.current && isScrollBottomInRange) { - canLoadBottom.current = false - - console.debug("[chat tab] loading bottom messages") - - loadAfter() - setPausedUpdates(false) - setScrollableToBottom(false) - } - - if (!isScrollBottomInRange && !canLoadBottom.current) { - canLoadBottom.current = true - setPausedUpdates(true) - setScrollableToBottom(true) - } - }, - [_id, loadAfter], - ) + const handleOnNewMessage = React.useCallback(() => { + if (!timelineRef.current || pausedUpdate) { + return + } - const headerRender = React.useCallback(() => { - return ( - <> - {scrollableToBottom && ( - - )} - - {usersTyping.length > 0 && ( -
- {usersTyping.map((user) => ( - {user.username} - ))} - is typing... -
- )} - - ) - }, [_id, usersTyping, scrollableToBottom]) + if (!scrollableToBottom) { + timelineRef.current.scrollTo(0, 0) + } + }, [timelineRef, pausedUpdate]) - useContentPanelHeaderRender(headerRender) + const handleOnScroll = React.useCallback((e) => { + const scrollPosition = Math.abs(timelineRef.current.scrollTop) + const isOnBottom = scrollPosition >= 0 && scrollPosition < 100 - // load more data when scroll is on top - React.useEffect(() => { - if (!loading && topTriggerInView.inView && canLoadTop.current) { - console.debug("[chat tab] loading more messages") + bottomTrigger(isOnBottom) - loadBefore() - canLoadTop.current = false + if (isOnBottom) { + setPausedUpdates(false) + setScrollableToBottom(false) + } else { + setPausedUpdates(true) + setScrollableToBottom(true) } + }, []) - if (!topTriggerInView.inView && !canLoadTop.current) { - canLoadTop.current = true + React.useEffect(() => { + if (initialLoading) { + return } - }, [loadBefore, topTriggerInView]) - React.useEffect(() => { if (timelineRef.current) { timelineRef.current.addEventListener("scroll", handleOnScroll) } @@ -167,50 +147,132 @@ const Chat = ({ type = "group", _id, group = {} }) => { ) } } - }, [timelineRef.current]) + }, [initialLoading, timelineRef.current]) if (error) { - return

Error: {error.message}

+ return ( + + ) } if (initialLoading) { - return

Loading...

+ return null } + const trimmedUsersTyping = usersTyping?.slice(0, 3) + const isUsersTypingOverflowing = usersTyping?.length > 3 + + const usernamesTyping = trimmedUsersTyping.reduce((str, user) => { + return `${str} ${user.username},` + }, "") + return (
-
- {timeline.map((item, index) => { - const headless = shouldMergeWithNextItem( - timeline[index + 1], - item, - ) - - return ( - - ) - })} - +
- + + {usersTyping.length > 0 && ( + +
+ {trimmedUsersTyping.map((user) => ( + {user.username} + ))} +
+ + + {usernamesTyping}{" "} + {isUsersTypingOverflowing && "and more,"}{" "} + are typing... + +
+ )} +
+ + {timeline.map((item, index) => { + const headless = shouldMergeWithNextItem( + timeline[index + 1], + item, + ) + + return ( + + ) + })} + +
+ +
+ + + {scrollableToBottom && ( + +
+ +
+
+ )} +
{ {!group?.loading && group?.channels && - group?.channels.map((channel) => ( - handleOnClickChannel(channel)} - invalid={ - !VALID_CHANNEL_KINDS.includes(channel.kind) - } - /> - ))} + group?.channels.items.map((channel) => { + const channelState = + group?.statedChannels?.[channel._id] + + const clients = channelState?.clients || [] + const producers = channelState?.producers || [] + + const startedAt = channelState?.started_at + + return ( + + handleOnClickChannel(channel) + } + invalid={ + !VALID_CHANNEL_KINDS.includes(channel.kind) + } + /> + ) + })}
) diff --git a/packages/app/src/components/Spaces/Group/ChannelsPanel/item/index.jsx b/packages/app/src/components/Spaces/Group/ChannelsPanel/item/index.jsx index 13bf9c44c..8acbcf4ac 100644 --- a/packages/app/src/components/Spaces/Group/ChannelsPanel/item/index.jsx +++ b/packages/app/src/components/Spaces/Group/ChannelsPanel/item/index.jsx @@ -9,7 +9,15 @@ import { Icons } from "@components/Icons" import "./index.less" -const ChannelsListItem = ({ channel, invalid, selected, handleOnClick }) => { +const ChannelsListItem = ({ + channel, + clients, + producers, + startedAt, + invalid, + selected, + handleOnClick, +}) => { if (!channel) { return null } @@ -50,7 +58,7 @@ const ChannelsListItem = ({ channel, invalid, selected, handleOnClick }) => { const rtcClient = getRtcClient(client) if (!rtcClient) { - return [...channel.producers].filter( + return [...producers].filter( (producer) => producer.user_id === client.userId, ) } @@ -68,7 +76,7 @@ const ChannelsListItem = ({ channel, invalid, selected, handleOnClick }) => { ["invalid"]: invalid, ["selected"]: selected, ["joined"]: isJoined, - ["empty"]: channel?.clients?.length === 0, + ["empty"]: clients?.length === 0, }, )} > @@ -92,10 +100,10 @@ const ChannelsListItem = ({ channel, invalid, selected, handleOnClick }) => {
)} - {channel.started_at && ( + {startedAt && (
@@ -104,17 +112,17 @@ const ChannelsListItem = ({ channel, invalid, selected, handleOnClick }) => {
- {channel?.clients?.length !== 0 && ( + {(clients?.length ?? 0) !== 0 && (
- {channel?.clients.map((client, index) => { + {clients?.map((client, index) => { return ( { ) } - if (content.type === "channel") { + if (content.type === "group") { return (

@@ -107,6 +107,6 @@ export const ContentPanelRender = () => { return React.createElement(Tabs[content.type].component, { ...content.props, - group: group.data, + group: group, }) } diff --git a/packages/app/src/components/Spaces/Group/GroupHeader/index.jsx b/packages/app/src/components/Spaces/Group/GroupHeader/index.jsx index 6bc909051..4f045d1d0 100644 --- a/packages/app/src/components/Spaces/Group/GroupHeader/index.jsx +++ b/packages/app/src/components/Spaces/Group/GroupHeader/index.jsx @@ -56,10 +56,17 @@ const GroupHeader = () => { return (

{data.cover && ( @@ -69,28 +76,16 @@ const GroupHeader = () => { )}
-
- -
-

{data.name}

-

{data.description}

-
-
- {data.owner_user_id === app.userData._id && ( +
) diff --git a/packages/app/src/components/Spaces/Group/GroupHeader/index.less b/packages/app/src/components/Spaces/Group/GroupHeader/index.less index ede09b22b..46e41af3d 100644 --- a/packages/app/src/components/Spaces/Group/GroupHeader/index.less +++ b/packages/app/src/components/Spaces/Group/GroupHeader/index.less @@ -1,13 +1,12 @@ .group-page__header { position: relative; + z-index: -1; + overflow: hidden; width: 100%; - height: 100%; - - max-height: 120px; - min-height: 120px; + height: fit-content; background-color: var(--background-color-accent); @@ -20,17 +19,43 @@ gap: 20px; &.cover_light { - color: var(--text-color-black); + .group-page__header__content__text { + color: var(--text-color-black); + } + } + + &.has_banner { + height: 100%; + + max-height: 120px; + min-height: 120px; + + .group-page__header__content { + height: 100%; + } + + .group-page__header__content__text { + opacity: 1; + + h1 { + -webkit-text-stroke: 1.5px rgba(var(--cover-av-color), 0.5); + } + } } &__cover { position: absolute; + + z-index: -1; + top: 0; left: 0; width: 100%; height: 100%; + opacity: 0.8; + .lazy-load-image-background { width: 100%; height: 100%; @@ -47,42 +72,24 @@ &__content { display: flex; flex-direction: row; - justify-items: center; + + align-items: flex-end; width: 100%; + height: fit-content; padding: 10px; gap: 20px; - backdrop-filter: blur(1px); - - &__icon { - width: 100px; - height: 100px; - - //background-color: var(--background-color-accent); - - border-radius: 12px; - overflow: hidden; - - .lazy-load-image-background { - width: 100%; - height: 100%; - - img { - width: 100%; - height: 100%; - - object-fit: cover; - } - } - } + // backdrop-filter: blur(1px); &__text { display: flex; flex-direction: column; justify-content: center; - gap: 10px; + + font-size: 0.9rem; + h1, h2, h3, @@ -97,16 +104,11 @@ } &__actions { - position: absolute; - - bottom: 0; - right: 0; - display: flex; flex-direction: row; - gap: 10px; + margin-left: auto; - padding: 10px; + gap: 10px; } } diff --git a/packages/app/src/components/Spaces/Group/MembersPanel/index.jsx b/packages/app/src/components/Spaces/Group/MembersPanel/index.jsx index e63a49301..3f63211e9 100644 --- a/packages/app/src/components/Spaces/Group/MembersPanel/index.jsx +++ b/packages/app/src/components/Spaces/Group/MembersPanel/index.jsx @@ -181,7 +181,7 @@ const MembersPanel = () => { const group = React.useContext(GroupContext) const { online, offline } = React.useMemo(() => { - const list = group?.members?.list || [] + const list = group?.members?.items || [] const connectedIds = group?.connectedMembers || [] const connectedSet = new Set(connectedIds) @@ -210,7 +210,7 @@ const MembersPanel = () => { } return { online: onlineList, offline: offlineList } - }, [group?.members?.list, group?.connectedMembers]) + }, [group?.members?.items, group?.connectedMembers]) return (
@@ -219,15 +219,15 @@ const MembersPanel = () => { Members - {group?.members?.total ?? 0} + {group?.members?.total_items ?? 0}
- {(group?.loading || !group?.members?.list) && } + {(group?.loading || !group?.members?.items) && } - {!group?.loading && group?.members?.list && ( + {!group?.loading && group?.members?.items && ( { +const Channel = ({ data, onClickDelete }) => { const { _id, name, description } = data return ( @@ -24,12 +24,13 @@ const Channel = ({ data }) => {
+ Delete
) } -const ChannelsList = () => { +const ChannelsList = ({ onDeleteChannel }) => { const group = React.useContext(GroupContext) const [channels, setChannels] = React.useState([]) @@ -39,7 +40,7 @@ const ChannelsList = () => { ) const hasChanges = () => { - const originalChannelsIds = R_Channels.map((c) => c._id) + const originalChannelsIds = R_Channels.items.map((c) => c._id) const channelsIds = channels.map((c) => c._id) // check if the channels orders are different @@ -67,7 +68,7 @@ const ChannelsList = () => { React.useEffect(() => { if (R_Channels) { - setChannels(R_Channels) + setChannels(R_Channels.items) } }, [R_Channels]) @@ -89,6 +90,7 @@ const ChannelsList = () => { onDeleteChannel(channel._id)} /> )} onChange={(arr) => { @@ -100,17 +102,30 @@ const ChannelsList = () => { } const ChannelsSettings = () => { + const group = React.useContext(GroupContext) + + const handleCreateNewChannel = async () => { + await GroupsModel.channels.create(group.data._id, { + name: "New channel", + kind: "chat", + }) + } + + const handleDeleteChannel = async (channel_id) => { + await GroupsModel.channels.channel.delete(group.data._id, channel_id) + } + return (

Channels

- +
- +
) } diff --git a/packages/app/src/components/Spaces/Group/settings/general/index.jsx b/packages/app/src/components/Spaces/Group/settings/general/index.jsx index daea2f2b6..86ac526f2 100644 --- a/packages/app/src/components/Spaces/Group/settings/general/index.jsx +++ b/packages/app/src/components/Spaces/Group/settings/general/index.jsx @@ -2,12 +2,16 @@ import React from "react" import { Input } from "antd" import Button from "@ui/Button" +import ConfirmButton from "@ui/ConfirmButton" import UploadButton from "@components/UploadButton" import { Icons } from "@components/Icons" +import Upload from "antd/es/upload/Upload" import GroupContext from "@contexts/WithSpaces/group" import GroupsModel from "@models/groups" +import "./index.less" + const GeneralSettings = () => { const group = React.useContext(GroupContext) @@ -18,7 +22,7 @@ const GeneralSettings = () => { icon: group?.data?.icon, cover: group?.data?.cover, } - }, []) + }, [group.data]) const [values, setValues] = React.useState(baseValues) @@ -38,6 +42,7 @@ const GeneralSettings = () => { const submit = async () => { console.log("submit", values) await GroupsModel.modify(group?.data?._id, values) + baseValues } const handleDeleteGroup = async () => { @@ -55,62 +60,106 @@ const GeneralSettings = () => { }) } + const handleLeaveGroup = async () => { + app.layout.modal.confirm({ + onConfirm: async () => { + await GroupsModel.leave(group?.data?._id) + + app.location.push("/spaces") + }, + }) + } + return (
- - - { - updateSetting("icon", response.url) - }} - /> +
+ Name +
+ +
+ { + updateSetting("name", e.target.value) + }} + /> +
- - - { - updateSetting("cover", response.url) - }} - /> +
+ Description +
+ +
+ { + updateSetting("description", e.target.value) + }} + /> +
- { - updateSetting("name", e.target.value) - }} - /> +
+ Images +
+ +
+ { + updateSetting("icon", response.url) + }} + > + Change Icon + + + { + updateSetting("cover", response.url) + }} + > + Change Banner + +
- { - updateSetting("description", e.target.value) - }} - /> +
+ Delete group +
+ +
+ + Delete + +
- +
+ Leave group +
+ +
+ + Leave + +
-
- ) - return ( -
-
+
+ {hasChanges() ? "Pending changes" : null} + +
+ setTermsAccept(e.target.checked)}> + I agree + + +
+ + {submitErr && {submitErr}} + {!termsAccept &&

Please review and agree to continue.

} +
+ ) +} + +export default OptInDialog diff --git a/packages/app/src/components/Spaces/OptInDialog/index.less b/packages/app/src/components/Spaces/OptInDialog/index.less new file mode 100644 index 000000000..b393132c1 --- /dev/null +++ b/packages/app/src/components/Spaces/OptInDialog/index.less @@ -0,0 +1,6 @@ +.spaces-optin-dialog { + display: flex; + flex-direction: column; + + gap: 10px; +} diff --git a/packages/app/src/context-menu/chat-line/index.js b/packages/app/src/context-menu/chat-line/index.js index afed06d08..de006dfe0 100644 --- a/packages/app/src/context-menu/chat-line/index.js +++ b/packages/app/src/context-menu/chat-line/index.js @@ -12,6 +12,18 @@ export default { return items } + items.push({ + label: "Reply", + icon: "ReplyAll", + action: () => { + control.close() + }, + }) + + items.push({ + type: "separator", + }) + items.push({ label: "Copy ID", icon: "Copy", diff --git a/packages/app/src/contexts/WithSpaces/chat/adapters.ts b/packages/app/src/contexts/WithSpaces/chat/adapters.ts new file mode 100644 index 000000000..79b6ff2b4 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/adapters.ts @@ -0,0 +1,264 @@ +import db from "../store" +import { Dexie } from "dexie" +import { Message } from "../collections/message" + +export interface ChatAdapter { + storeMessage: (message: Message) => Promise + deleteMessage: (id: string) => Promise + checkMessageExists: (id: string) => Promise + getCachedMessages: ( + params: any, + limit: number, + beforeId?: string, + afterId?: string, + ) => Promise + cacheMessages: (messages: Message[]) => Promise + invalidateCache: ( + messages: Message[], + beforeId: string, + afterId: string, + params: any, + ) => Promise +} + +export const groupAdapter: ChatAdapter = { + storeMessage: async (message: Message) => { + await db.channel_messages.add(message) + await db.last_channels_message.put({ + channel_id: message.channel_id, + _id: message._id, + }) + }, + deleteMessage: async (id) => { + await db.channel_messages.where("_id").equals(id).delete() + }, + checkMessageExists: async (id) => { + const msg = await db.channel_messages.where("_id").equals(id).first() + return !!msg + }, + getCachedMessages: async (params, limit, beforeId, afterId) => { + if (beforeId) { + return db.channel_messages + .where("[channel_id+_id]") + .between( + [params.channel_id, Dexie.minKey], + [params.channel_id, beforeId], + ) + .reverse() + .limit(limit) + .toArray() + } + + if (afterId) { + const msgs = await db.channel_messages + .where("[channel_id+_id]") + .between( + [params.channel_id, afterId], + [params.channel_id, Dexie.maxKey], + false, + true, + ) + .limit(limit) + .toArray() + return msgs.reverse() + } + + return db.channel_messages + .where("[channel_id+_id]") + .between( + [params.channel_id, Dexie.minKey], + [params.channel_id, Dexie.maxKey], + ) + .reverse() + .limit(limit) + .toArray() + }, + cacheMessages: async (messages: Message[]) => { + if (!Array.isArray(messages)) { + console.error("Failed to cache messages, messages is not an Array") + return + } + + messages = messages.map((msg) => { + msg.cached_at = Date.now() + + delete msg.user + + return msg + }) + + await db.channel_messages.bulkPut(messages) + + // const lastMessage = messages.at(0) + // console.log("cacheMessages::lastMessage", lastMessage) + + // if (lastMessage) { + // await db.last_channels_message.put({ + // channel_id: lastMessage.channel_id, + // _id: lastMessage._id, + // }) + // } + }, + invalidateCache: async ( + cache: Message[], + beforeId: string, + afterId: string, + params: any, + ) => { + if (!params || !params.channel_id) { + return true + } + + const lastChannelMessageRef = await db.last_channels_message.get( + params.channel_id, + ) + + // if no last message ref is stored, invalidate cache + if (!lastChannelMessageRef) { + return true + } + + const oldestItem = cache.at(-1) as Message + const newestItem = cache.at(0) as Message + + console.log("Checking valid cache", { + cache, + beforeId, + afterId, + oldestItem, + newestItem, + lastChannelMessageRef, + }) + + if (!afterId && !beforeId) { + if (!newestItem) { + return true + } + + if ( + parseInt(newestItem._id) < parseInt(lastChannelMessageRef._id) + ) { + return true + } + } + + // if query is beforeId, check if the newest item in the cache + // is older than the last channel message, + // if its, invalidate cache + if (beforeId) { + if (!oldestItem) { + return true + } + + if ( + parseInt(oldestItem._id) < parseInt(lastChannelMessageRef._id) + ) { + return true + } + } + + // if the oldest message is older than specified afterId, invalidate cache + // also check if the afterId is minor than the last channel message + if (afterId) { + if (parseInt(lastChannelMessageRef._id) >= parseInt(afterId)) { + return false + } + + if (!newestItem) { + return true + } + + if (parseInt(newestItem._id) < parseInt(afterId)) { + return true + } + } + + return false + }, +} + +export const dmAdapter: ChatAdapter = { + storeMessage: async (message) => { + await db.direct_messages.put(message).catch(console.error) + }, + deleteMessage: async (id) => { + // we use catch because the store schema might not have _id indexed + try { + // @ts-ignore + await db.direct_messages.where("_id").equals(id).delete() + } catch (e) { + console.error(e) + } + }, + checkMessageExists: async (id) => { + try { + // @ts-ignore + const msg = await db.direct_messages.where("_id").equals(id).first() + return !!msg + } catch (e) { + return false + } + }, + getCachedMessages: async (params, limit, beforeId, afterId) => { + if (beforeId) { + return db.direct_messages + .where("[to_user_id+_id]") + .between( + [params.to_user_id, Dexie.minKey], + [params.to_user_id, beforeId], + ) + .reverse() + .limit(limit) + .toArray() + } + if (afterId) { + const msgs = await db.direct_messages + .where("[to_user_id+_id]") + .between( + [params.to_user_id, afterId], + [params.to_user_id, Dexie.maxKey], + false, + true, + ) + .limit(limit) + .toArray() + return msgs.reverse() + } + return db.direct_messages + .where("[to_user_id+_id]") + .between( + [params.to_user_id, Dexie.minKey], + [params.to_user_id, Dexie.maxKey], + ) + .reverse() + .limit(limit) + .toArray() + }, + cacheMessages: async (messages) => { + await db.direct_messages.bulkPut( + messages.map((msg) => ({ ...msg, cached_at: Date.now() })), + ) + }, + invalidateCache: async ( + messages: Message[], + beforeId: string, + afterId: string, + ) => { + return true + }, +} + +export const adapters: Record = { + group: groupAdapter, + dm: dmAdapter, +} + +export const getAdapter = (type: string): ChatAdapter => { + const adapter = adapters[type] + + if (!adapter) { + throw new Error(`invalid chat type: ${type}`) + } + + return adapter +} diff --git a/packages/app/src/contexts/WithSpaces/chat/configs/dm.ts b/packages/app/src/contexts/WithSpaces/chat/configs/dm.ts new file mode 100644 index 000000000..c25fad689 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/configs/dm.ts @@ -0,0 +1,36 @@ +// @ts-ignore +import ChatsModel from "@models/chats" + +export default { + events: { + message: "channel:message", + messageUpdated: "channel:message:updated", + messageDeleted: "channel:message:deleted", + typing: "channel:typing", + }, + methods: { + send: "dm:send", + subscribe: "dm:subscribe", + unsubscribe: "dm:unsubscribe", + typing: "dm:typing", + }, + model: { + get: (params, options) => ChatsModel.dm.get(params.to_user_id, options), + }, + params: { + send: (params, data) => ({ + to_user_id: params.to_user_id, + ...data, + }), + subscribe: (params) => ({ + to_user_id: params.to_user_id, + }), + unsubscribe: (params) => ({ + to_user_id: params.to_user_id, + }), + typing: (params, isTyping) => ({ + isTyping, + to_user_id: params.to_user_id, + }), + }, +} diff --git a/packages/app/src/contexts/WithSpaces/chat/configs/group.ts b/packages/app/src/contexts/WithSpaces/chat/configs/group.ts new file mode 100644 index 000000000..23f61eb1b --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/configs/group.ts @@ -0,0 +1,45 @@ +// @ts-ignore +import ChatsModel from "@models/chats" + +export default { + events: { + message: "channel:message", + messageUpdated: "channel:message:updated", + messageDeleted: "channel:message:deleted", + typing: "channel:typing", + }, + methods: { + send: "channel:send", + subscribe: "channel:subscribe", + unsubscribe: "channel:unsubscribe", + typing: "channel:typing", + }, + model: { + get: (params, options) => + ChatsModel.channels.get( + params.group_id, + params.channel_id, + options, + ), + }, + params: { + send: (params, data) => ({ + group_id: params.group_id, + channel_id: params.channel_id, + ...data, + }), + subscribe: (params) => ({ + group_id: params.group_id, + channel_id: params.channel_id, + }), + unsubscribe: (params) => ({ + group_id: params.group_id, + channel_id: params.channel_id, + }), + typing: (params, isTyping) => ({ + isTyping, + group_id: params.group_id, + channel_id: params.channel_id, + }), + }, +} diff --git a/packages/app/src/contexts/WithSpaces/chat/index.ts b/packages/app/src/contexts/WithSpaces/chat/index.ts new file mode 100644 index 000000000..57a434ed2 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/index.ts @@ -0,0 +1,160 @@ +import React from "react" +import { useChatMessages } from "./useChatMessages" +import { useChatTyping } from "./useChatTyping" +import { useChatSocket } from "./useChatSocket" + +import db from "../store" +import { getAdapter } from "./adapters" +import { Message } from "../collections/message" +import sortMessages from "../utils/sortMessages" + +import DM_CONFIG from "./configs/dm" +import GROUP_CONFIG from "./configs/group" + +const CHAT_CONFIGS: Record = { + group: GROUP_CONFIG, + dm: DM_CONFIG, +} + +function useChat(type: string, params: any, events: any) { + const config = CHAT_CONFIGS[type] + + if (!config) { + throw new Error(`invalid chat type: ${type}. must be 'group' or 'dm'`) + } + + const adapter = React.useMemo(() => getAdapter(type), [type]) + + const depKey = + type === "group" + ? `${type}:${params.group_id}:${params.channel_id}` + : `${type}:${params.to_user_id}` + + const { + timeline, + setTimeline, + loading, + initialLoading, + setInitialLoading, + hasMore, + setHasMore, + error: messagesError, + setError: setMessagesError, + load, + loadBefore, + loadAfter, + send: sendMessages, + handleNewMessage, + handleMessageDeleted, + handleMessageUpdated, + setPausedUpdates, + pausedUpdates, + resetMessages, + } = useChatMessages({ + type: type, + config: config, + params: params, + events: events, + }) + + const { isTyping, usersTyping, typing, handleTypingEvent, resetTyping } = + useChatTyping(config, params) + + const { error: socketError } = useChatSocket({ + config, + params, + depKey, + onNewMessage: handleNewMessage, + onMessageUpdated: handleMessageUpdated, + onMessageDeleted: handleMessageDeleted, + onTyping: handleTypingEvent, + }) + + const send = React.useCallback( + (payload: any) => sendMessages(payload, () => typing(false)), + [sendMessages, typing], + ) + + const initialize = async () => { + const cachedMessages = await adapter.getCachedMessages(params, 50) + const lastCachedMessage = cachedMessages.at(0) as Message + + if (type === "group") { + const lastChannelMessageRef = await db.last_channels_message.get( + params.channel_id, + ) + + console.log({ + lastChannelMessageRef, + lastCachedMessage, + }) + + if ( + !lastCachedMessage || + parseInt(lastCachedMessage?._id) < + parseInt(lastChannelMessageRef?._id) + ) { + console.debug("Cached messages is expired, fetching new...") + await load() + } else { + setTimeline(sortMessages(cachedMessages)) + } + } + + if (type === "dm") { + // TODO: lookup the last dm message ref for this room + await load() + } + } + + React.useEffect(() => { + setInitialLoading(true) + let isMounted = true + + resetMessages() + resetTyping() + + initialize() + .catch((err: any) => { + if (isMounted) { + setMessagesError(err) + } + }) + .finally(() => { + if (isMounted) { + setInitialLoading(false) + } + }) + + return () => { + isMounted = false + } + }, [ + depKey, + load, + resetMessages, + resetTyping, + setInitialLoading, + setMessagesError, + ]) + + return { + initialLoading, + timeline, + loading, + error: messagesError || socketError, + loadBefore, + loadAfter, + load, + send, + typing, + isTyping, + usersTyping, + pausedUpdates, + setPausedUpdates, + hasMore, + setHasMore, + } +} + +export default useChat diff --git a/packages/app/src/contexts/WithSpaces/chat/useChatMessages.ts b/packages/app/src/contexts/WithSpaces/chat/useChatMessages.ts new file mode 100644 index 000000000..62b493c97 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/useChatMessages.ts @@ -0,0 +1,294 @@ +import React from "react" +import userDataMap from "../helpers/usersDataMap" +import { getAdapter } from "./adapters" +import { getSocket } from "./useChatSocket" +import { Message } from "../collections/message" +import { User } from "../collections/user" +import { + DeleteMessagePayload, + LoadMessagesParams, + T_UseChatMessagesArgs, +} from "../types" + +import { cacheUsers } from "../helpers/cache" +import sortMessages from "../utils/sortMessages" + +import db from "../store" + +export function useChatMessages({ + type, + config, + params, + events, +}: T_UseChatMessagesArgs) { + const socket = React.useMemo(() => getSocket(), [params]) + const adapter = React.useMemo(() => getAdapter(type), [type]) + + const [initialLoading, setInitialLoading] = React.useState(true) + const [loading, setLoading] = React.useState(false) + const loadingRef = React.useRef(false) + + const [timeline, setTimeline] = React.useState([]) + const [error, setError] = React.useState(null) + + const [hasMore, setHasMore] = React.useState(true) + const hasMoreRef = React.useRef(true) + + const paramsRef = React.useRef(params) + const eventsRef = React.useRef(events) + const pausedUpdatesRef = React.useRef(false) + const oldestId = React.useRef(null) + const newestId = React.useRef(null) + + React.useEffect(() => { + paramsRef.current = params + eventsRef.current = events + }, [params, events]) + + React.useEffect(() => { + if (timeline.length > 0) { + oldestId.current = timeline[timeline.length - 1]._id + newestId.current = timeline[0]._id + } + }, [timeline]) + + const pushToTimeline = React.useCallback( + (messages: Message[], position: string) => { + if (!position) { + position = "top" + } + + setTimeline((prev) => { + if (position === "top") { + return sortMessages([...prev, ...messages]) + } + + if (position === "bottom") { + return sortMessages([...messages, ...prev]) + } + }) + }, + [setTimeline], + ) + + const handleNewMessage = React.useCallback( + (data: Message) => { + console.debug("useChat::handleNewMessage", data) + + try { + adapter.storeMessage(data) + } catch (err) { + console.error("failed to store message to local db", err) + } + + if (!pausedUpdatesRef.current) { + pushToTimeline([data], "bottom") + } + + if (typeof eventsRef.current?.onNewMessage === "function") { + eventsRef.current.onNewMessage(data) + } + }, + [type], + ) + + const handleMessageDeleted = React.useCallback( + (data: DeleteMessagePayload) => { + console.debug("useChat::handleMessageDeleted", data) + + try { + adapter.deleteMessage(data._id) + } catch (err) { + console.error("failed to delete message from local db", err) + } + + setTimeline((prev) => prev.filter((msg) => msg._id !== data._id)) + + if (typeof eventsRef.current?.onDeletedMessage === "function") { + eventsRef.current.onDeletedMessage(data) + } + }, + [type], + ) + + const handleMessageUpdated = React.useCallback((data: any) => { + eventsRef.current?.onUpdatedMessage?.(data) + }, []) + + const send = React.useCallback( + async ( + { message, attachments = [], sticker }: any = {}, + stopTyping?: () => void, + ) => { + if (!message && attachments.length === 0 && !sticker) { + return null + } + + const formattedAttachments = attachments.map((att: any) => + typeof att === "string" + ? { url: att } + : { url: att.url, hash: att.hash }, + ) + + const data = config.params.send(paramsRef.current, { + message, + attachments: formattedAttachments, + sticker, + }) + + if (socket) { + await socket.call(config.methods.send, data) + } + + if (stopTyping) { + stopTyping() + } + + return true + }, + [config], + ) + + const load = React.useCallback( + async ({ beforeId, afterId, limit = 30 }: LoadMessagesParams = {}) => { + if (loadingRef.current === true) { + console.warn("Waiting to finish loading messages...") + return + } + + if (afterId && beforeId) { + throw new Error( + "only one of beforeId or afterId can be provided", + ) + } + + setLoading(true) + loadingRef.current = true + + try { + const currentParams = paramsRef.current + const adapter = getAdapter(type) + + let data: { + items: Message[] + users: User[] + } = { + items: [], + users: [], + } + + const cachedMessages = await adapter.getCachedMessages( + currentParams, + limit, + beforeId, + afterId, + ) + + let isCacheInvalidated = await adapter.invalidateCache( + cachedMessages, + beforeId, + afterId, + { + channel_id: currentParams.channel_id, + }, + ) + + if (isCacheInvalidated) { + console.time("useChat::load::apiFetchMessages") + const response = await config.model.get(currentParams, { + limit: limit, + beforeId, + afterId, + }) + console.timeEnd("useChat::load::apiFetchMessages") + + if (response.items.length > 0) { + // cache users from api + if (response.users) { + await cacheUsers(response.users) + } + + data.items = response.items + + try { + await adapter.cacheMessages(data.items) + } catch (error) { + console.error("failed to cache messages:", error) + } + } else { + setHasMore(false) + hasMoreRef.current = false + } + } else { + data.items = cachedMessages + } + + if (data.items.length > 0) { + data.users = await db.users + .where("_id") + .anyOf(data.items.map((message) => message.user_id)) + .toArray() + } + + console.log({ data }) + pushToTimeline(data.items, afterId ? "top" : "bottom") + } catch (err: any) { + console.error("error loading historical messages:", err) + setError(err) + } finally { + setLoading(false) + loadingRef.current = false + } + }, + [config, type], + ) + + const loadBefore = React.useCallback( + (id?: string) => load({ beforeId: id ?? oldestId.current! }), + [load], + ) + + const loadAfter = React.useCallback( + (id?: string) => load({ afterId: id ?? newestId.current! }), + [load], + ) + + const setPausedUpdates = React.useCallback((to: boolean) => { + pausedUpdatesRef.current = to + }, []) + + const resetMessages = React.useCallback(() => { + setTimeline([]) + setInitialLoading(true) + + setLoading(false) + loadingRef.current = false + + setHasMore(true) + hasMoreRef.current = true + + setError(null) + }, []) + + return { + timeline, + setTimeline, + loading, + initialLoading, + setInitialLoading, + hasMore, + setHasMore, + error, + setError, + load, + loadBefore, + loadAfter, + send, + handleNewMessage, + handleMessageDeleted, + handleMessageUpdated, + setPausedUpdates, + pausedUpdates: pausedUpdatesRef.current, + resetMessages, + } +} diff --git a/packages/app/src/contexts/WithSpaces/chat/useChatSocket.ts b/packages/app/src/contexts/WithSpaces/chat/useChatSocket.ts new file mode 100644 index 000000000..cf085b862 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/useChatSocket.ts @@ -0,0 +1,77 @@ +import React from "react" + +export const getSocket = () => + globalThis.__comty_shared_state?.ws?.sockets?.get("main") + +export function useChatSocket({ + config, + params, + depKey, + onNewMessage, + onMessageUpdated, + onMessageDeleted, + onTyping, +}: any) { + const [error, setError] = React.useState(null) + + // use refs to avoid unnecessary resubscriptions + const callbacksRef = React.useRef({ + onNewMessage, + onMessageUpdated, + onMessageDeleted, + onTyping, + }) + + React.useEffect(() => { + callbacksRef.current = { + onNewMessage, + onMessageUpdated, + onMessageDeleted, + onTyping, + } + }) + + React.useEffect(() => { + const socket = getSocket() + + if (!socket) { + setError(new Error("chat websocket not available or found")) + return + } + + setError(null) + + const subscribeParams = config.params.subscribe(params) + + const handleNewMessage = (data: any) => + callbacksRef.current.onNewMessage?.(data) + const handleMessageUpdated = (data: any) => + callbacksRef.current.onMessageUpdated?.(data) + const handleMessageDeleted = (data: any) => + callbacksRef.current.onMessageDeleted?.(data) + const handleTypingEvent = (data: any) => + callbacksRef.current.onTyping?.(data) + + socket.on(config.events.message, handleNewMessage) + socket.on(config.events.messageUpdated, handleMessageUpdated) + socket.on(config.events.messageDeleted, handleMessageDeleted) + socket.on(config.events.typing, handleTypingEvent) + + socket.topics + .subscribe(config.methods.subscribe, subscribeParams) + .catch(console.error) + + return () => { + socket.off(config.events.message, handleNewMessage) + socket.off(config.events.messageUpdated, handleMessageUpdated) + socket.off(config.events.messageDeleted, handleMessageDeleted) + socket.off(config.events.typing, handleTypingEvent) + + socket.topics + .unsubscribe(config.methods.unsubscribe, subscribeParams) + .catch(console.error) + } + }, [depKey, config]) + + return { error, setError } +} diff --git a/packages/app/src/contexts/WithSpaces/chat/useChatTyping.ts b/packages/app/src/contexts/WithSpaces/chat/useChatTyping.ts new file mode 100644 index 000000000..21c070f95 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/chat/useChatTyping.ts @@ -0,0 +1,86 @@ +import React from "react" +import { getSocket } from "./useChatSocket" + +export function useChatTyping(config: any, params: any) { + const [isTyping, setIsTyping] = React.useState(false) + const [usersTyping, setUsersTyping] = React.useState([]) + + const typingTimeout = React.useRef(null) + const isTypingNetworkState = React.useRef(false) + const paramsRef = React.useRef(params) + + React.useEffect(() => { + paramsRef.current = params + }, [params]) + + const handleTypingEvent = React.useCallback((data: any) => { + setUsersTyping((prev) => { + const userId = data.user_id || data.user?.id || data.user?._id + + if (data.isTyping) { + const isExisting = prev.some( + (u) => u.id === userId || u._id === userId, + ) + + return isExisting + ? prev + : [...prev, { id: userId, ...data.user }] + } + + return prev.filter((u) => u.id !== userId && u._id !== userId) + }) + }, []) + + const typing = React.useCallback( + (isTypingNow = true) => { + setIsTyping(isTypingNow) + + if (typingTimeout.current) { + clearTimeout(typingTimeout.current) + } + + if (isTypingNetworkState.current !== isTypingNow) { + isTypingNetworkState.current = isTypingNow + + getSocket() + ?.call( + config.methods.typing, + config.params.typing(paramsRef.current, isTypingNow), + ) + .catch((err: any) => + console.error("error setting typing state:", err), + ) + } + + if (isTypingNow) { + typingTimeout.current = setTimeout(() => typing(false), 5000) + } + }, + [config], + ) + + const resetTyping = React.useCallback(() => { + setUsersTyping([]) + setIsTyping(false) + isTypingNetworkState.current = false + if (typingTimeout.current) { + clearTimeout(typingTimeout.current) + } + }, []) + + React.useEffect(() => { + return () => { + if (typingTimeout.current) { + clearTimeout(typingTimeout.current) + } + } + }, []) + + return { + isTyping, + usersTyping, + typing, + handleTypingEvent, + resetTyping, + } +} diff --git a/packages/app/src/contexts/WithSpaces/collections/channel.ts b/packages/app/src/contexts/WithSpaces/collections/channel.ts new file mode 100644 index 000000000..a78921c82 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/channel.ts @@ -0,0 +1,34 @@ +// @ts-ignore +import { Producer } from "@cores/mediartc/classes/Producers" +import { Client } from "./client" + +export interface Channel { + _id: string + group_id: string + kind: "chat" | "voice" + + name: string + description?: string + explicit: boolean + + last_message_id?: string + + created_at: Date + cached_at?: number +} + +export interface Channels { + group_id?: string + cached_at?: number + + items: Channel[] + total_items?: number + has_more?: boolean +} + +export interface StatedChannel { + _id?: string + clients: Client[] + producers?: Producer[] + started_at?: string | Date | null +} diff --git a/packages/app/src/contexts/WithSpaces/collections/client.ts b/packages/app/src/contexts/WithSpaces/collections/client.ts new file mode 100644 index 000000000..f6336f59e --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/client.ts @@ -0,0 +1,9 @@ +import { VoiceState } from "./voiceState" + +export interface Client { + channel_id: string + userId: string + voiceState: VoiceState + user?: any + self?: boolean +} diff --git a/packages/app/src/contexts/WithSpaces/collections/group.ts b/packages/app/src/contexts/WithSpaces/collections/group.ts new file mode 100644 index 000000000..a102c145c --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/group.ts @@ -0,0 +1,22 @@ +import type { Channels } from "./channel" +import type { Members } from "./member" + +export interface Group { + _id: string + owner_user_id: string + + name: string + description: string + + icon?: string + cover?: string + groupCoverImageAverageColor?: string + + channels: Channels + members: Members + + connected_members?: string[] + + __v?: number + cached_at?: number +} diff --git a/packages/app/src/contexts/WithSpaces/collections/member.ts b/packages/app/src/contexts/WithSpaces/collections/member.ts new file mode 100644 index 000000000..070f2bc98 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/member.ts @@ -0,0 +1,19 @@ +export interface Member { + _id: string + group_id: string + user_id: string + roles?: any + created_at?: string + + user?: any + cached_at?: number +} + +export interface Members { + items: Member[] + total_items?: number + has_more?: boolean + + group_id?: string + cached_at?: number +} diff --git a/packages/app/src/contexts/WithSpaces/collections/message.ts b/packages/app/src/contexts/WithSpaces/collections/message.ts new file mode 100644 index 000000000..1e2438189 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/message.ts @@ -0,0 +1,21 @@ +import { User } from "./user" + +export interface Message { + __v?: number + cached_at?: number + + user?: User + + _id: string + channel_id: string + user_id: string + + message?: string + attachments?: [Map] + flags?: [string] + sticker?: string + reply_to_id?: string + + created_at: Date + updated_at?: Date +} diff --git a/packages/app/src/contexts/WithSpaces/collections/producer.ts b/packages/app/src/contexts/WithSpaces/collections/producer.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/app/src/contexts/WithSpaces/collections/user.ts b/packages/app/src/contexts/WithSpaces/collections/user.ts new file mode 100644 index 000000000..652cf4799 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/user.ts @@ -0,0 +1,21 @@ +export interface User { + __v?: number + cached_at?: number + + _id: string + user_id: string + + username: string + + public_name?: string + description?: string + + avatar: string + cover?: string + + decorations?: Record + links?: Record + + roles?: string[] + verified?: boolean +} diff --git a/packages/app/src/contexts/WithSpaces/collections/voiceState.ts b/packages/app/src/contexts/WithSpaces/collections/voiceState.ts new file mode 100644 index 000000000..1af73bedb --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/collections/voiceState.ts @@ -0,0 +1,4 @@ +export interface VoiceState { + muted: boolean + deafen: boolean +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelCreated.ts b/packages/app/src/contexts/WithSpaces/group/events/channelCreated.ts new file mode 100644 index 000000000..e4b426c4e --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelCreated.ts @@ -0,0 +1,25 @@ +import { EventsUpdaters } from ".." +import { Channel } from "../../collections/channel" + +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: Channel, +) => { + updaters.setChannels((prev) => { + const nw = { ...prev } + + nw.items.push(payload) + + try { + db.channels.update(currentGroupId, nw) + } catch (error) { + console.error(`Failed to update db cache`, error) + db.channels.delete(currentGroupId) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelDeleted.ts b/packages/app/src/contexts/WithSpaces/group/events/channelDeleted.ts new file mode 100644 index 000000000..d6f19db62 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelDeleted.ts @@ -0,0 +1,24 @@ +import { EventsUpdaters } from ".." +import { Channel } from "../../collections/channel" +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: Channel, +) => { + updaters.setChannels((prev) => { + const nw = { ...prev } + + nw.items = nw.items.filter((channel) => channel._id !== payload._id) + + try { + db.channels.update(currentGroupId, nw) + } catch (error) { + console.error(`Failed to update db cache`, error) + db.channels.delete(currentGroupId) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelDeletedMessage.ts b/packages/app/src/contexts/WithSpaces/group/events/channelDeletedMessage.ts new file mode 100644 index 000000000..188a29272 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelDeletedMessage.ts @@ -0,0 +1,12 @@ +import { EventsUpdaters } from ".." +import { Message } from "../../collections/message" + +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: Message, +) => { + console.debug("group channelDeletedMessage", payload) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelNewMessage.ts b/packages/app/src/contexts/WithSpaces/group/events/channelNewMessage.ts new file mode 100644 index 000000000..641d2d5d6 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelNewMessage.ts @@ -0,0 +1,19 @@ +import { EventsUpdaters } from ".." +import { Message } from "../../collections/message" + +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: Message, +) => { + console.debug("group channelNewMessage", payload) + + if (payload?.channel_id) { + db.last_channels_message.put({ + channel_id: payload.channel_id, + _id: payload._id, + }) + } +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelUpdated.ts b/packages/app/src/contexts/WithSpaces/group/events/channelUpdated.ts new file mode 100644 index 000000000..b9af0d01b --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelUpdated.ts @@ -0,0 +1,33 @@ +import { EventsUpdaters } from ".." +import { Channel } from "../../collections/channel" + +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: Channel, +) => { + updaters.setChannels((prev) => { + const channelIndex = prev.items.findIndex( + (channel) => channel._id === payload._id, + ) + + if (channelIndex == -1) { + return prev + } + + const nw = { ...prev } + + nw.items[channelIndex] = payload + + try { + db.channels.update(currentGroupId, nw) + } catch (error) { + console.error(`Failed to update db cache`, error) + db.channels.delete(currentGroupId) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/channelsOrdered.ts b/packages/app/src/contexts/WithSpaces/group/events/channelsOrdered.ts new file mode 100644 index 000000000..4cdfb6819 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/channelsOrdered.ts @@ -0,0 +1,30 @@ +import { EventsUpdaters } from ".." +import { Channel } from "../../collections/channel" +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: string[], +) => { + if (!Array.isArray(payload)) { + return null + } + + updaters.setChannels((prev) => { + const nw = { ...prev } + + nw.items = nw.items.sort((a, b) => { + return payload.indexOf(a._id) - payload.indexOf(b._id) + }) + + try { + db.channels.update(currentGroupId, nw) + } catch (error) { + console.error(`Failed to update db cache`, error) + db.channels.delete(currentGroupId) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientEvent.js b/packages/app/src/contexts/WithSpaces/group/events/clientEvent.js deleted file mode 100644 index 5e6ba099c..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/clientEvent.js +++ /dev/null @@ -1,31 +0,0 @@ -export default (_, payload, setChannels) => { - switch (payload.event) { - case "updateVoiceState": - setChannels((prev) => { - const channelIndex = prev.findIndex( - (channel) => channel._id === payload.channelId, - ) - const clientIndex = - channelIndex > -1 - ? prev[channelIndex].clients.findIndex( - (client) => client.userId === payload.userId, - ) - : -1 - - if (clientIndex === -1) { - return prev - } - - const client = prev[channelIndex].clients[clientIndex] - - return prev.with(channelIndex, { - ...prev[channelIndex], - clients: prev[channelIndex].clients.with(clientIndex, { - ...client, - voiceState: { ...client.voiceState, ...payload.data }, - }), - }) - }) - break - } -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientEvent.ts b/packages/app/src/contexts/WithSpaces/group/events/clientEvent.ts new file mode 100644 index 000000000..80976bb36 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/clientEvent.ts @@ -0,0 +1,46 @@ +import { EventsUpdaters } from ".." + +export interface ClientEventPayload { + event: string + channelId: string + userId: string + data: any +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: ClientEventPayload, +): void => { + switch (payload.event) { + case "updateVoiceState": + updaters.setStatedChannels((prev) => { + if (!prev[payload.channelId]) { + return prev + } + + const nw = { ...prev } + + const clientIndex = nw[payload.channelId].clients.findIndex( + (client) => client.userId === payload.userId, + ) + + if (clientIndex === -1) { + return prev + } + + const client = nw[payload.channelId].clients[clientIndex] + + nw[payload.channelId].clients = nw[ + payload.channelId + ].clients.with(clientIndex, { + ...client, + voiceState: { ...client.voiceState, ...payload.data }, + }) + + return nw + }) + + break + } +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.js b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.js deleted file mode 100644 index acb5ca7f6..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.js +++ /dev/null @@ -1,20 +0,0 @@ -// update the group channel array if a client joins or leaves a channel -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - // update the clients of the channel - if (channel._id === payload.channelId) { - channel.clients.push({ - userId: payload.userId, - user: payload.user, - voiceState: payload.voiceState, - self: payload.userId === app.userData._id, - }) - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.ts b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.ts new file mode 100644 index 000000000..e47734e73 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelJoin.ts @@ -0,0 +1,37 @@ +import { EventsUpdaters } from ".." +import { Client } from "../../collections/client" + +export interface ClientVoiceChannelJoinPayload { + channelId: string + userId: string + user: any + voiceState: any +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: ClientVoiceChannelJoinPayload, +): void => { + updaters.setStatedChannels((prev) => { + const client: Client = { + channel_id: payload.channelId, + userId: payload.userId, + user: payload.user, + voiceState: payload.voiceState, + self: payload.userId === app.userData._id, + } + + if (!prev[payload.channelId]) { + prev[payload.channelId] = { + _id: payload.channelId, + clients: [], + producers: [], + } + } + + prev[payload.channelId].clients.push(client) + + return prev + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.js b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.js deleted file mode 100644 index bb3ee5cc7..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.js +++ /dev/null @@ -1,17 +0,0 @@ -// update the group channel array if a client joins or leaves a channel -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - // update the clients of the channel - if (channel._id === payload.channelId) { - channel.clients = channel.clients.filter( - (client) => client.userId !== payload.userId, - ) - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.ts b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.ts new file mode 100644 index 000000000..c1a0145ae --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelLeft.ts @@ -0,0 +1,30 @@ +import { EventsUpdaters } from ".." + +export interface ClientVoiceChannelLeftPayload { + channelId: string + userId: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: ClientVoiceChannelLeftPayload, +): void => { + updaters.setStatedChannels((prev) => { + if (!prev[payload.channelId]) { + return prev + } + + prev[payload.channelId].clients = prev[ + payload.channelId + ].clients.filter((client) => { + if (client.userId === payload.userId) { + return false + } + + return true + }) + + return prev + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.js b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.js deleted file mode 100644 index ced0e04a1..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.js +++ /dev/null @@ -1,21 +0,0 @@ -// update the group channel array if a client joins or leaves a channel -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - if (!channel.producers) { - channel.producers = [] - } - - // update the clients of the channel - if (channel._id === payload.channelId) { - channel.producers = channel.producers.filter( - (producer) => producer.id !== payload.producer.id, - ) - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.ts b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.ts new file mode 100644 index 000000000..c051ddf51 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerClose.ts @@ -0,0 +1,27 @@ +import { EventsUpdaters } from ".." + +export interface ClientVoiceChannelProducerClosePayload { + channelId: string + producer: { + id: string + [key: string]: any + } +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: ClientVoiceChannelProducerClosePayload, +): void => { + updaters.setStatedChannels((prev) => { + if (!prev[payload.channelId]) { + return prev + } + + prev[payload.channelId].producers = prev[ + payload.channelId + ].producers.filter((producer) => producer.id !== payload.producer.id) + + return prev + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.js b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.js deleted file mode 100644 index 218ba0492..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.js +++ /dev/null @@ -1,18 +0,0 @@ -// update the group channel array if a client joins or leaves a channel -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - if (!channel.producers) { - channel.producers = [] - } - // update the clients of the channel - if (channel._id === payload.channelId) { - channel.producers.push(payload.producer) - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.ts b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.ts new file mode 100644 index 000000000..a1b60f6e9 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/clientVoiceChannelProducerOpen.ts @@ -0,0 +1,26 @@ +import { EventsUpdaters } from ".." + +export interface ClientVoiceChannelProducerOpenPayload { + channelId: string + producer: any +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: ClientVoiceChannelProducerOpenPayload, +): void => { + updaters.setStatedChannels((prev) => { + if (!prev[payload.channelId]) { + prev[payload.channelId] = { + _id: payload.channelId, + clients: [], + producers: [], + } + } + + prev[payload.channelId].producers.push(payload.producer) + + return prev + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/groupUpdate.ts b/packages/app/src/contexts/WithSpaces/group/events/groupUpdate.ts new file mode 100644 index 000000000..6c6125675 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/groupUpdate.ts @@ -0,0 +1,21 @@ +import { EventsUpdaters } from ".." +import db from "../../store" + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: any, +): void => { + console.debug("Group data updated", payload) + + updaters.setData(() => { + try { + db.groups.update(payload._id, payload) + } catch (err) { + console.error(`Failed to update db cache`, err) + db.groups.delete(payload._id) + } + + return payload + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/index.ts b/packages/app/src/contexts/WithSpaces/group/events/index.ts new file mode 100644 index 000000000..cc970a82e --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/index.ts @@ -0,0 +1,112 @@ +import clientEvent, { ClientEventPayload } from "./clientEvent" +import clientVoiceChannelJoin, { + ClientVoiceChannelJoinPayload, +} from "./clientVoiceChannelJoin" +import clientVoiceChannelLeft, { + ClientVoiceChannelLeftPayload, +} from "./clientVoiceChannelLeft" +import clientVoiceChannelProducerClose, { + ClientVoiceChannelProducerClosePayload, +} from "./clientVoiceChannelProducerClose" +import clientVoiceChannelProducerOpen, { + ClientVoiceChannelProducerOpenPayload, +} from "./clientVoiceChannelProducerOpen" +import userOffline, { UserOfflinePayload } from "./userOffline" +import userOnline, { UserOnlinePayload } from "./userOnline" +import voiceChannelEnd, { VoiceChannelEndedPayload } from "./voiceChannelEnd" +import voiceChannelStarted, { + VoiceChannelStartedPayload, +} from "./voiceChannelStarted" +import { EventsUpdaters } from ".." +import membershipCreated, { + MemberchipCreatedPayload, +} from "./membershipCreated" +import membershipDeleted, { + MemberchipDeletedPayload, +} from "./membershipDeleted" +import groupUpdate from "./groupUpdate" +import channelCreated from "./channelCreated" +import channelDeleted from "./channelDeleted" +import channelUpdated from "./channelUpdated" +import channelsOrdered from "./channelsOrdered" +import channelNewMessage from "./channelNewMessage" +import channelDeletedMessage from "./channelDeletedMessage" + +export default ({ + group_id, + updaters, +}: { + group_id: string + updaters: EventsUpdaters +}) => { + const groupTopicPrefix = `group:${group_id}` + + return { + // + // Group events + // + [`${groupTopicPrefix}:update`]: (payload: any) => + groupUpdate(group_id, updaters, payload), + + // + // Channels Events + // + [`${groupTopicPrefix}:channel:created`]: (payload: any) => + channelCreated(group_id, updaters, payload), + [`${groupTopicPrefix}:channel:deleted`]: (payload: any) => + channelDeleted(group_id, updaters, payload), + [`${groupTopicPrefix}:channel:updated`]: (payload: any) => + channelUpdated(group_id, updaters, payload), + [`${groupTopicPrefix}:channels:ordered`]: (payload: any) => + channelsOrdered(group_id, updaters, payload), + + [`${groupTopicPrefix}:channels:new:message`]: (payload: any) => + channelNewMessage(group_id, updaters, payload), + [`${groupTopicPrefix}:channels:deleted:message`]: (payload: any) => + channelDeletedMessage(group_id, updaters, payload), + // [`${groupTopicPrefix}:channels:updated:message`]: (payload: any) => + // channelNewMessage(group_id, updaters, payload), + + // + // Memberships Events + // + [`${groupTopicPrefix}:membership:created`]: ( + payload: MemberchipCreatedPayload, + ) => membershipCreated(group_id, updaters, payload), + [`${groupTopicPrefix}:membership:deleted`]: ( + payload: MemberchipDeletedPayload, + ) => membershipDeleted(group_id, updaters, payload), + + // + // Voice Channels events + // + [`${groupTopicPrefix}:vc:started`]: ( + payload: VoiceChannelStartedPayload, + ) => voiceChannelStarted(group_id, updaters, payload), + [`${groupTopicPrefix}:vc:ended`]: (payload: VoiceChannelEndedPayload) => + voiceChannelEnd(group_id, updaters, payload), + [`${groupTopicPrefix}:client:vc:join`]: ( + payload: ClientVoiceChannelJoinPayload, + ) => clientVoiceChannelJoin(group_id, updaters, payload), + [`${groupTopicPrefix}:client:vc:left`]: ( + payload: ClientVoiceChannelLeftPayload, + ) => clientVoiceChannelLeft(group_id, updaters, payload), + [`${groupTopicPrefix}:client:vc:event`]: ( + payload: ClientEventPayload, + ) => clientEvent(group_id, updaters, payload), + [`${groupTopicPrefix}:client:vc:producer:open`]: ( + payload: ClientVoiceChannelProducerOpenPayload, + ) => clientVoiceChannelProducerOpen(group_id, updaters, payload), + [`${groupTopicPrefix}:client:vc:producer:close`]: ( + payload: ClientVoiceChannelProducerClosePayload, + ) => clientVoiceChannelProducerClose(group_id, updaters, payload), + + // + // Group users Events + // + [`${groupTopicPrefix}:user:online`]: (payload: UserOnlinePayload) => + userOnline(group_id, updaters, payload), + [`${groupTopicPrefix}:user:offline`]: (payload: UserOfflinePayload) => + userOffline(group_id, updaters, payload), + } +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/membershipCreated.ts b/packages/app/src/contexts/WithSpaces/group/events/membershipCreated.ts new file mode 100644 index 000000000..f1cad42f1 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/membershipCreated.ts @@ -0,0 +1,48 @@ +import { EventsUpdaters } from ".." +import db from "../../store" +import UserModel from "@models/user" + +export interface MemberchipCreatedPayload { + group_id: string + membership_id: string + user_id: string + user?: any +} + +export default async ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: MemberchipCreatedPayload, +) => { + console.debug("membershipCreated", payload) + + if (!payload.user) { + payload.user = await UserModel.data({ + user_id: payload.user_id, + basic: true, + }) + } + + // update members + updaters.setMembers((prev) => { + const nw = { ...prev } + + nw.total_items = nw.total_items + 1 + + nw.items.push({ + _id: payload.membership_id, + group_id: payload.group_id, + user_id: payload.user_id, + user: payload.user, + }) + + try { + db.members.update(payload.group_id, nw) + } catch (err) { + console.error(`Failed to update db cache`, err) + db.members.delete(payload.group_id) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/membershipDeleted.ts b/packages/app/src/contexts/WithSpaces/group/events/membershipDeleted.ts new file mode 100644 index 000000000..f6b45e18a --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/membershipDeleted.ts @@ -0,0 +1,40 @@ +import { EventsUpdaters } from ".." +import db from "../../store" + +export interface MemberchipDeletedPayload { + membership_id: string + user_id: string + group_id: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: MemberchipDeletedPayload, +) => { + console.debug("membershipDeleted", payload) + + // update members + updaters.setMembers((prev) => { + const nw = { ...prev } + + nw.total_items = nw.total_items - 1 + + nw.items = nw.items.filter((member) => { + if (member.user_id === payload.user_id) { + return false + } + + return true + }) + + try { + db.members.update(payload.group_id, nw) + } catch (err) { + console.error(`Failed to update db cache`, err) + db.members.delete(payload.group_id) + } + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/userOffline.js b/packages/app/src/contexts/WithSpaces/group/events/userOffline.ts similarity index 52% rename from packages/app/src/contexts/WithSpaces/group/events/userOffline.js rename to packages/app/src/contexts/WithSpaces/group/events/userOffline.ts index b81eda912..c2be4a937 100644 --- a/packages/app/src/contexts/WithSpaces/group/events/userOffline.js +++ b/packages/app/src/contexts/WithSpaces/group/events/userOffline.ts @@ -1,7 +1,17 @@ -export default (data, setData, payload) => { +import { EventsUpdaters } from ".." + +export interface UserOfflinePayload { + userId: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: UserOfflinePayload, +): void => { console.debug("User switch to offline", payload) - setData((prev) => { + updaters.setConnectedMembers((prev) => { let connected_members = [...prev] if (connected_members.includes(payload.userId)) { diff --git a/packages/app/src/contexts/WithSpaces/group/events/userOnline.js b/packages/app/src/contexts/WithSpaces/group/events/userOnline.js deleted file mode 100644 index d417737b4..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/userOnline.js +++ /dev/null @@ -1,13 +0,0 @@ -export default (data, setData, payload) => { - console.debug("User switch to connected", payload) - - setData((prev) => { - const connected_members = [...prev] - - if (!connected_members.includes(payload.userId)) { - connected_members.push(payload.userId) - } - - return connected_members - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/userOnline.ts b/packages/app/src/contexts/WithSpaces/group/events/userOnline.ts new file mode 100644 index 000000000..65ce7ca5c --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/userOnline.ts @@ -0,0 +1,23 @@ +import { EventsUpdaters } from ".." + +export interface UserOnlinePayload { + userId: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: UserOnlinePayload, +): void => { + console.debug("User switch to connected", payload) + + updaters.setConnectedMembers((prev) => { + const connected_members = [...prev] + + if (!connected_members.includes(payload.userId)) { + connected_members.push(payload.userId) + } + + return connected_members + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.js b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.js deleted file mode 100644 index 8bef0f5a8..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.js +++ /dev/null @@ -1,16 +0,0 @@ -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - // update the clients of the channel - if (channel._id === payload.channelId) { - if (channel.started_at) { - delete channel.started_at - } - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.ts b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.ts new file mode 100644 index 000000000..120f951d3 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelEnd.ts @@ -0,0 +1,25 @@ +import { EventsUpdaters } from ".." + +export interface VoiceChannelEndedPayload { + channelId: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: VoiceChannelEndedPayload, +): void => { + console.log("vc:end", payload) + + updaters.setStatedChannels((prev) => { + const nw = { ...prev } + + if (!nw[payload.channelId]) { + return nw + } + + delete nw[payload.channelId] + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStarted.ts b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStarted.ts new file mode 100644 index 000000000..44d1bdc24 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStarted.ts @@ -0,0 +1,28 @@ +import { EventsUpdaters } from ".." + +export interface VoiceChannelStartedPayload { + channelId: string + started_at?: string +} + +export default ( + currentGroupId: string, + updaters: EventsUpdaters, + payload: VoiceChannelStartedPayload, +): void => { + updaters.setStatedChannels((prev) => { + const nw = { ...prev } + + if (!nw[payload.channelId]) { + nw[payload.channelId] = { + _id: payload.channelId, + clients: [], + producers: [], + } + } + + nw[payload.channelId].started_at = payload.started_at + + return nw + }) +} diff --git a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStated.js b/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStated.js deleted file mode 100644 index 60a71a484..000000000 --- a/packages/app/src/contexts/WithSpaces/group/events/voiceChannelStated.js +++ /dev/null @@ -1,16 +0,0 @@ -export default (data, setChannels, payload) => { - setChannels((prev) => { - const channels = prev.map((channel) => { - // update the clients of the channel - if (channel._id === payload.channelId) { - if (payload.started_at) { - channel.started_at = payload.started_at - } - } - - return channel - }) - - return channels - }) -} diff --git a/packages/app/src/contexts/WithSpaces/group/index.js b/packages/app/src/contexts/WithSpaces/group/index.js deleted file mode 100644 index fdb0d866a..000000000 --- a/packages/app/src/contexts/WithSpaces/group/index.js +++ /dev/null @@ -1,286 +0,0 @@ -import React from "react" -import GroupsModel from "@models/groups" - -import onUserOnlineEvent from "./events/userOnline" -import onUserOfflineEvent from "./events/userOffline" -import onClientEvent from "./events/clientEvent" - -import onClientVoiceChannelJoinEvent from "./events/clientVoiceChannelJoin" -import onClientVoiceChannelLeftEvent from "./events/clientVoiceChannelLeft" -import onClientVoiceChannelProducerOpenEvent from "./events/clientVoiceChannelProducerOpen" -import onClientVoiceChannelProducerCloseEvent from "./events/clientVoiceChannelProducerClose" - -import onVoiceChannelStated from "./events/voiceChannelStated" -import onVoiceChannelEnded from "./events/voiceChannelEnd" - -const VALID_CHANNEL_KINDS = ["chat", "voice"] - -const getInitialMembersState = () => ({ - total: 0, - hasMore: false, - list: [], -}) - -const DEFAULT_CHANNELS_STATE = [] - -const DEFAULT_CONTEXT_DATA = { - _id: null, - name: null, - description: null, - cover: null, - owner_user_id: null, - groupCoverImageAverageColor: null, - channels: [], - connected_members: [], - members: {}, -} - -const useGroup = ({ group_id }) => { - if (!group_id) { - throw new Error("group_id is required") - } - - const socket = React.useRef(app.cores.api.socket()) - - const [loading, setLoading] = React.useState(true) - const [error, setError] = React.useState(null) - - const [data, setData] = React.useState(null) - const [members, setMembers] = React.useState(getInitialMembersState) - const [channels, setChannels] = React.useState(DEFAULT_CHANNELS_STATE) - const [connectedMembers, setConnectedMembers] = React.useState([]) - - const lastLoadedMemberId = React.useRef(null) - - const dataRef = React.useRef(data) - - React.useEffect(() => { - dataRef.current = data - }, [data]) - - const fetchMembers = React.useCallback(async () => { - try { - const result = await GroupsModel.members.list(group_id, { - offset: lastLoadedMemberId.current, - }) - - if (result.items.length > 0) { - lastLoadedMemberId.current = result.items[0]._id - } - - setMembers((prev) => ({ - list: [...prev.list, ...result.items], - total: result.total_items, - hasMore: result.has_more, - })) - } catch (err) { - console.error("Error fetching more members:", err) - } - }, [group_id]) - - const loadChannelsStates = React.useCallback( - async (channelsList, currentGroupId) => { - const remoteState = - await GroupsModel.rtc.getGroupState(currentGroupId) - - for (let channel of channelsList) { - if (!Array.isArray(remoteState.channels)) { - continue - } - - const currentStateChannel = remoteState.channels.find( - (_c) => _c._id === channel._id, - ) - - if (!currentStateChannel) { - continue - } - - if (currentStateChannel.clients) { - channel.clients = currentStateChannel.clients - } - - if (currentStateChannel.producers) { - channel.producers = currentStateChannel.producers - } - - if (currentStateChannel.started_at) { - channel.started_at = currentStateChannel.started_at - } - } - - if (remoteState.connected_members) { - setConnectedMembers(remoteState.connected_members) - } - - return channelsList - }, - [], - ) - - React.useEffect(() => { - if (error) { - app.cores.notifications.new({ - type: "error", - title: "Failed to load group", - description: error.message, - }) - } - }, [error]) - - React.useEffect(() => { - if (!group_id) { - return undefined - } - - let isActive = true - - const loadInitialData = async () => { - setLoading(true) - setError(null) - setData(null) - setMembers(getInitialMembersState()) - setChannels(DEFAULT_CHANNELS_STATE) - setConnectedMembers([]) - lastLoadedMemberId.current = null - - try { - const group = await GroupsModel.get(group_id) - - if (!isActive) { - return null - } - - const membersResult = await GroupsModel.members.list(group_id, { - offset: null, - }) - - if (!isActive) { - return null - } - - if (membersResult.items.length > 0) { - lastLoadedMemberId.current = membersResult.items[0]._id - } - - setMembers({ - list: membersResult.items, - total: membersResult.total_items, - hasMore: membersResult.has_more, - }) - - let channelsList = await GroupsModel.channels.list(group._id) - - if (!isActive) { - return null - } - - channelsList = channelsList.map((channel) => ({ - ...channel, - clients: [], - producers: [], - })) - - channelsList = await loadChannelsStates(channelsList, group_id) - - if (!isActive) { - return null - } - - setData(group) - setChannels(channelsList) - } catch (err) { - if (isActive) { - setError(err) - } - } finally { - if (isActive) { - setLoading(false) - } - } - } - - loadInitialData() - - const events = { - [`group:${group_id}:vc:started`]: (payload) => - onVoiceChannelStated(dataRef.current, setChannels, payload), - [`group:${group_id}:vc:ended`]: (payload) => - onVoiceChannelEnded(dataRef.current, setChannels, payload), - - [`group:${group_id}:client:vc:join`]: (payload) => - onClientVoiceChannelJoinEvent( - dataRef.current, - setChannels, - payload, - ), - [`group:${group_id}:client:vc:left`]: (payload) => - onClientVoiceChannelLeftEvent( - dataRef.current, - setChannels, - payload, - ), - [`group:${group_id}:client:vc:event`]: (payload) => - onClientEvent(dataRef.current, payload, setChannels), - [`group:${group_id}:client:vc:producer:open`]: (payload) => - onClientVoiceChannelProducerOpenEvent( - dataRef.current, - setChannels, - payload, - ), - [`group:${group_id}:client:vc:producer:close`]: (payload) => - onClientVoiceChannelProducerCloseEvent( - dataRef.current, - setChannels, - payload, - ), - [`group:${group_id}:user:online`]: (payload) => - onUserOnlineEvent( - dataRef.current, - setConnectedMembers, - payload, - ), - [`group:${group_id}:user:offline`]: (payload) => - onUserOfflineEvent( - dataRef.current, - setConnectedMembers, - payload, - ), - } - - if (socket.current) { - socket.current.topics.subscribe("group:subscribe", group_id) - - for (const [event, handler] of Object.entries(events)) { - socket.current.on(event, handler) - } - } - - return () => { - isActive = false - - if (socket.current) { - socket.current.topics.subscribe("group:unsubscribe", group_id) - - for (const [event, handler] of Object.entries(events)) { - socket.current.off(event, handler) - } - } - } - }, [group_id, loadChannelsStates]) - - return { - data, - channels, - members, - connectedMembers, - loading, - error, - fetchMembers, - } -} - -const GroupContext = React.createContext(DEFAULT_CONTEXT_DATA) - -export { VALID_CHANNEL_KINDS, DEFAULT_CONTEXT_DATA, GroupContext, useGroup } -export default GroupContext diff --git a/packages/app/src/contexts/WithSpaces/group/index.ts b/packages/app/src/contexts/WithSpaces/group/index.ts new file mode 100644 index 000000000..2bd0cb932 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/group/index.ts @@ -0,0 +1,341 @@ +import React from "react" +// @ts-ignore +import GroupsModel from "@models/groups" +import buildSocketEvents from "./events" +import loadChannelsStates from "../helpers/loadChannelsStates" +import { + cacheGroup, + cacheChannels, + cacheMembers, + cacheTotalMembers, +} from "../helpers/cache" + +import db from "../store" + +import type { Group } from "../collections/group" +import type { Channel, Channels, StatedChannel } from "../collections/channel" +import type { Member, Members } from "../collections/member" +import { GroupState } from "../types" + +const VALID_CHANNEL_KINDS = ["chat", "voice"] as const + +export interface EventsUpdaters { + setData: React.Dispatch> + setChannels: React.Dispatch> + setMembers: React.Dispatch> + setConnectedMembers: React.Dispatch> + setStatedChannels: React.Dispatch< + React.SetStateAction> + > +} + +const DEFAULT_CHANNELS_STATE = () => ({ + items: [], + total_items: 0, + has_more: false, +}) +const DEFAULT_MEMBERS_STATE = () => ({ + items: [], + total_items: 0, + has_more: false, +}) +const DEFAULT_GROUP_STATE = () => ({ + _id: null, + name: null, + description: null, + cover: null, + owner_user_id: null, + groupCoverImageAverageColor: null, + connected_members: [], + channels: { + items: [], + total_items: 0, + has_more: false, + }, + members: { + items: [], + total_items: 0, + has_more: false, + }, +}) + +const useGroup = ({ group_id }) => { + if (!group_id) { + throw new Error("group_id is required") + } + + const socket = React.useRef(app.cores.api.socket()) + + const [loading, setLoading] = React.useState(true) + const [error, setError] = React.useState(null) + + const [data, setData] = React.useState(null) + const [members, setMembers] = React.useState(null) + const [channels, setChannels] = React.useState(null) + + const [statedChannels, setStatedChannels] = React.useState< + Record + >({}) + const [connectedMembers, setConnectedMembers] = React.useState([]) + + const lastLoadedMemberId = React.useRef(null) + + const fetchGroup = React.useCallback(async () => { + const res = await GroupsModel.get(group_id) + + setData(res) + await cacheGroup(res) + + return res + }, [group_id]) + + const fetchChannels = React.useCallback(async () => { + const res = await GroupsModel.channels.list(group_id) + + setChannels(res) + await cacheChannels(group_id, res) + + return res + }, [group_id]) + + const fetchMembers = React.useCallback(async () => { + try { + const res = await GroupsModel.members.list(group_id, { + offset: lastLoadedMemberId.current, + }) + + if (res.items.length > 0) { + lastLoadedMemberId.current = res.items[0]._id + } + + // update cache + setMembers(res) + await cacheMembers(res) + await cacheTotalMembers(group_id, res.total_items) + + return res + } catch (err) { + console.error("Error fetching more members:", err) + } + }, [group_id]) + + const syncWithState = React.useCallback(async () => { + const groupState = (await GroupsModel.rtc.getGroupState( + group_id, + )) as GroupState + + if (groupState?.connected_members) { + setConnectedMembers(groupState.connected_members) + } + + if (groupState?.rtc) { + setStatedChannels( + (groupState.rtc as unknown as StatedChannel[]).reduce( + (curr, channel) => { + curr[channel._id] = channel + return curr + }, + {}, + ), + ) + } + + // cache the channels + if (groupState?.channels && Array.isArray(groupState?.channels)) { + try { + //setChannels(groupState.channels) + //cacheChannels(group_id, groupState.channels) + } catch (error) { + console.error("Failed to sync to local db", error) + } + } + + // update last_channels_messages + if ( + groupState?.last_channels_messages && + Array.isArray(groupState?.last_channels_messages) + ) { + await db.last_channels_message.bulkPut( + groupState.last_channels_messages, + ) + } + + return groupState + }, [group_id]) + + const load = React.useCallback(async () => { + setLoading(true) + setError(null) + + let cached = { + group: null, + + memberships: null, + total_members: 0, + + channels: null, + } as { + group: Group | null + + memberships: Member[] | null + total_members: number | null + + channels: Channels | null + } + + try { + cached.group = await db.groups.get(group_id) + + cached.channels = await db.channels.get(group_id) + + cached.memberships = await db.members + .where("group_id") + .equals(group_id) + .limit(50) + .toArray() + + cached.total_members = + (await db.members_counter.get(group_id)).counter ?? 0 + } catch (error) { + console.error("Failed to get cached content", error) + } + + console.log("useGroup::load()", { + group_id, + cached, + }) + + try { + // + // fetch the group data + // + if (!cached.group || !cached.group?.cached_at) { + console.time("group.get()") + cached.group = await fetchGroup() + console.timeEnd("group.get()") + } else { + setData(cached.group) + } + + // + // fetch the members list + // + if (!cached.memberships || cached.memberships.length === 0) { + console.time("members.list()") + await fetchMembers() + console.timeEnd("members.list()") + } else { + setMembers({ + items: cached.memberships, + total_items: cached.total_members, + }) + } + + // + // fetch the channels list + // + if (!cached.channels || !cached.channels?.cached_at) { + console.time("channels.list()") + cached.channels = await fetchChannels() + console.timeEnd("channels.list()") + } else { + setChannels(cached.channels) + } + + const state = await syncWithState() + + if ((cached.group.__v ?? 0) < (state.group.__v ?? 0)) { + console.log("Group Version invalidates the cache") + await fetchGroup() + } + + if (cached.total_members < state.total_members) { + await fetchMembers() + } + } catch (err) { + console.error(err) + setError(err as Error) + } finally { + setLoading(false) + } + }, [group_id, data, members, channels]) + + React.useEffect(() => { + if (error) { + app.cores.notifications.new({ + type: "error", + title: "Failed to load group", + description: error.message, + }) + } + }, [error]) + + React.useEffect(() => { + console.log("useGroup | group_id changed", group_id) + + if (!group_id) { + return undefined + } + + load() + + const events = buildSocketEvents({ + group_id: group_id, + updaters: { + setData, + setChannels, + setMembers, + setStatedChannels, + setConnectedMembers, + }, + }) + + if (socket.current) { + socket.current.topics.subscribe("group:subscribe", group_id) + + for (const [event, handler] of Object.entries(events)) { + socket.current.on(event, handler) + } + } + + return () => { + setConnectedMembers([]) + lastLoadedMemberId.current = null + + if (socket.current) { + socket.current.topics.subscribe("group:unsubscribe", group_id) + + for (const [event, handler] of Object.entries(events)) { + socket.current.off(event, handler) + } + } + } + }, [group_id]) + + return { + data: data, + channels: channels, + members: members, + + statedChannels: statedChannels, + connectedMembers: connectedMembers, + + loading, + error, + + load, + fetchMembers, + fetchChannels, + fetchGroup, + } +} + +const GroupContext = React.createContext(DEFAULT_GROUP_STATE()) + +export { + VALID_CHANNEL_KINDS, + DEFAULT_GROUP_STATE as DEFAULT_CONTEXT_DATA, + GroupContext, + useGroup, +} +export default GroupContext diff --git a/packages/app/src/contexts/WithSpaces/helpers/cache.ts b/packages/app/src/contexts/WithSpaces/helpers/cache.ts new file mode 100644 index 000000000..56e5446aa --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/helpers/cache.ts @@ -0,0 +1,89 @@ +import { Channels } from "../collections/channel" +import { Group } from "../collections/group" +import { Members } from "../collections/member" +import { User } from "../collections/user" + +import db from "../store" + +// cache group data +export const cacheGroup = async (group: Group): Promise => { + try { + await db.groups.put({ + ...group, + channels: { items: [], total_items: 0, has_more: false }, + members: { items: [], total_items: 0, has_more: false }, + cached_at: Date.now(), + }) + } catch (err) { + console.error("Error caching group:", err) + } +} + +// cache members list +export const cacheMembers = async (members: Members): Promise => { + try { + members.items = members.items.map((member) => { + member.cached_at = Date.now() + + return member + }) + + await db.members.bulkPut(members.items) + } catch (err) { + console.error("Error caching members:", err) + } +} + +export const cacheTotalMembers = async (group_id: string, counter: number) => { + try { + await db.members_counter.put({ + group_id: group_id, + counter: counter, + }) + } catch (err) { + console.error("Error caching total members:", err) + } +} + +// cache channels list +export const cacheChannels = async ( + group_id: string, + channels: Channels, +): Promise => { + try { + channels.group_id = group_id + channels.cached_at = Date.now() + + await db.channels.put(channels) + } catch (err) { + console.error("Error caching channels:", err) + } +} + +export const cacheUsers = async (users: User[]) => { + try { + if (!Array.isArray(users)) { + throw new Error(`"users" must be a array`) + } + + users = users.map((user) => { + user.cached_at = Date.now() + return user + }) + + await db.users.bulkPut(users) + } catch (error) { + console.error("Error caching users", error) + } +} + +// clear cache for a group +export const clearGroupCache = async (group_id: string): Promise => { + try { + await db.members.where("group_id").equals(group_id).delete() + await db.channels.where("group_id").equals(group_id).delete() + await db.groups.delete(group_id) + } catch (err) { + console.error("Error clearing group cache:", err) + } +} diff --git a/packages/app/src/contexts/WithSpaces/helpers/loadChannelsStates.ts b/packages/app/src/contexts/WithSpaces/helpers/loadChannelsStates.ts new file mode 100644 index 000000000..1e16c6d1a --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/helpers/loadChannelsStates.ts @@ -0,0 +1,54 @@ +import { StatedChannels } from "../collections/channel" + +export default async ({ + channels, + groupState, +}: { + channels: StatedChannels + groupState: any +}) => { + if (!groupState) { + throw new Error("`groupState` is not defined") + } + + if (!channels && !Array.isArray(channels?.items)) { + throw new Error("`channels.items` is not array") + } + + // iterate all provided channels + for (let channel of channels.items) { + // mutate with the state objects + channel.clients = [] + channel.producers = [] + channel.started_at = null + + // check if has states for channels + if (!Array.isArray(groupState.channels)) { + continue + } + + // find the state + const chState = groupState.channels.find( + (_c: any) => _c._id === channel._id, + ) + + // if not founded, just continue with the next + if (!chState) { + continue + } + + if (chState.clients) { + channel.clients = chState.clients + } + + if (chState.producers) { + channel.producers = chState.producers + } + + if (chState.started_at) { + channel.started_at = chState.started_at + } + } + + return channels +} diff --git a/packages/app/src/contexts/WithSpaces/helpers/usersDataMap.js b/packages/app/src/contexts/WithSpaces/helpers/usersDataMap.js new file mode 100644 index 000000000..0f1fcfa97 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/helpers/usersDataMap.js @@ -0,0 +1,17 @@ +function userDataMap(data) { + const users = new Map(data.users.map((user) => [user._id, user])) + + data.items = data.items.map((item) => { + item.user = users.get(item.user_id) ?? { + username: "unknown", + public_name: "Ghost", + unknown: true, + } + + return item + }) + + return data +} + +export default userDataMap diff --git a/packages/app/src/contexts/WithSpaces/store.ts b/packages/app/src/contexts/WithSpaces/store.ts new file mode 100644 index 000000000..d4d297076 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/store.ts @@ -0,0 +1,59 @@ +import { Dexie, type EntityTable } from "dexie" +import { Group } from "./collections/group" +import { Channels } from "./collections/channel" +import { Member, Members } from "./collections/member" + +import { Message } from "./collections/message" +import { User } from "./collections/user" + +type LastChannelsMessage = { + channel_id: string + _id: string +} + +type MembersCounter = { + group_id: string + counter: number +} + +type GroupEntitySyncTime = { + group_id: string + time: Date +} + +const db = new Dexie("spaces_store") as Dexie & { + groups: EntityTable + + channels: EntityTable + channels_sync: EntityTable + + members: EntityTable + members_counter: EntityTable + members_sync: EntityTable + + channel_messages: EntityTable + last_channels_message: EntityTable + + direct_messages: EntityTable + users: EntityTable +} + +db.version(1).stores({ + groups: "_id", + + channels: "group_id", + channels_sync: "group_id", + + members: "_id, group_id, [group_id+_id]", + members_counter: "group_id", + members_sync: "group_id", + + channel_messages: "_id, channel_id, [channel_id+_id]", + last_channels_message: "channel_id", + + direct_messages: "_id, to_user_id, [to_user_id+_id]", + + users: "_id", +}) + +export default db diff --git a/packages/app/src/contexts/WithSpaces/types.d.ts b/packages/app/src/contexts/WithSpaces/types.d.ts new file mode 100644 index 000000000..c1e972b51 --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/types.d.ts @@ -0,0 +1,38 @@ +import { Channel, StatedChannel } from "./collections/channel" +import { Group } from "./collections/group" +import { Member } from "./collections/member" + +type T_UseChatMessagesArgs = { + type: string + config: any + params: any + events: any + channel?: any +} + +type LastChannelsMessages = { + channel_id: string + _id: string +} + +type GroupState = { + group: Group + + total_members: number + memberships: Member[] + + last_channels_messages: LastChannelsMessages[] + rtc: StatedChannel[] + channels: Channel[] + connected_members: string[] +} + +export type DeleteMessagePayload = { + _id: string // the message id +} + +export type LoadMessagesParams = { + beforeId?: string + afterId?: string + limit?: number +} diff --git a/packages/app/src/contexts/WithSpaces/utils/sortMessages.ts b/packages/app/src/contexts/WithSpaces/utils/sortMessages.ts new file mode 100644 index 000000000..821d981fd --- /dev/null +++ b/packages/app/src/contexts/WithSpaces/utils/sortMessages.ts @@ -0,0 +1,15 @@ +import { Message } from "../collections/message" + +export default (arr: Message[]) => { + return arr.sort((a, b) => { + if (a._id > b._id) { + return -1 + } + + if (a._id < b._id) { + return 1 + } + + return 0 + }) +} diff --git a/packages/app/src/cores/api/api.core.js b/packages/app/src/cores/api/api.core.js index d29f91c6f..fce7f6a30 100755 --- a/packages/app/src/cores/api/api.core.js +++ b/packages/app/src/cores/api/api.core.js @@ -104,6 +104,9 @@ export default class APICore extends Core { }) } }, + "wsmanager:main:open": () => { + this.console.log("Main socket open") + }, } getWebsocketClient(namespace) { @@ -184,7 +187,7 @@ export default class APICore extends Core { } async onInitialize() { - this.client = createClient({ + this.client = await createClient({ eventBus: app.eventBus, ws: { enable: true, diff --git a/packages/app/src/cores/mediartc/classes/AudioProcessor.js b/packages/app/src/cores/mediartc/classes/AudioProcessor.js index ff13ab12b..11a19500a 100644 --- a/packages/app/src/cores/mediartc/classes/AudioProcessor.js +++ b/packages/app/src/cores/mediartc/classes/AudioProcessor.js @@ -27,6 +27,7 @@ export default class AudioProcessor { } this.mainNode = this.context.createGain() + this.mainNode.gain.value = 1 } lastNode = null diff --git a/packages/app/src/cores/mediartc/classes/Producers.ts b/packages/app/src/cores/mediartc/classes/Producers.ts index 88179096c..46c2caa9a 100644 --- a/packages/app/src/cores/mediartc/classes/Producers.ts +++ b/packages/app/src/cores/mediartc/classes/Producers.ts @@ -1,20 +1,17 @@ import MediaRTC from "../mediartc.core" import { types as mediasoup } from "mediasoup-client" -export interface ProducerData extends mediasoup.Producer { +export interface Producer extends mediasoup.Producer { id: string producerId: string remote?: boolean self?: boolean } -export default class Producers extends Map { +export default class Producers extends Map { core: MediaRTC - constructor( - core: MediaRTC, - data?: Iterable, - ) { + constructor(core: MediaRTC, data?: Iterable) { super(data) this.core = core @@ -23,7 +20,7 @@ export default class Producers extends Map { } } - setRemote(producer: ProducerData): ProducerData | null { + setRemote(producer: Producer): Producer | null { if (!producer) { return null } @@ -36,7 +33,7 @@ export default class Producers extends Map { return producer } - delRemote(producer: ProducerData): ProducerData | null { + delRemote(producer: Producer): Producer | null { if (!producer) { return null } @@ -45,13 +42,13 @@ export default class Producers extends Map { this.core.state.remoteProducers = this.core.state.remoteProducers.filter( - (p: ProducerData) => p.producerId !== producer.producerId, + (p: Producer) => p.producerId !== producer.producerId, ) return producer } - produce = async (payload: any): Promise => { + produce = async (payload: any): Promise => { if (!this.core.device || !this.core.sendTransport) { throw new Error("Device or send transport not ready") } @@ -85,7 +82,7 @@ export default class Producers extends Map { return producer } - onSelfProducerClosed = (producer: ProducerData) => { + onSelfProducerClosed = (producer: Producer) => { if (!producer) { return null } diff --git a/packages/app/src/cores/mediartc/classes/Self.ts b/packages/app/src/cores/mediartc/classes/Self.ts index 6772460ca..51cc42225 100644 --- a/packages/app/src/cores/mediartc/classes/Self.ts +++ b/packages/app/src/cores/mediartc/classes/Self.ts @@ -4,7 +4,7 @@ import SysAudio from "./SysAudio" import defaults from "../defaults" -import type { ProducerData } from "./Producers" +import type { Producer } from "./Producers" type CreateScreenStreamOptions = { resolution?: { width: number; height: number } @@ -24,14 +24,14 @@ export default class Self { core: MediaRTC micStream: MediaStream = null - micProducer: ProducerData = null + micProducer: Producer = null camStream: MediaStream = null - camProducer: ProducerData = null + camProducer: Producer = null screenStream: MediaStream = null - screenProducer: ProducerData = null - screenAudioProducer: ProducerData = null + screenProducer: Producer = null + screenAudioProducer: Producer = null audioInput = null audioOutput = @@ -92,19 +92,17 @@ export default class Self { if (key === "inputGain") { app.cores.settings.set("mediartc:inputGain", value) - const inputGainParameter = - app.cores.mediartc.instance().self.audioInput.mainNode.gain - - inputGainParameter.value = value + if (this.audioInput && this.audioInput?.mainNode) { + this.audioInput.mainNode.gain.value = value + } } if (key === "outputGain") { app.cores.settings.set("mediartc:outputGain", value) - const outputGainParameter = - app.cores.mediartc.instance().self.audioOutput.mainNode.gain - - outputGainParameter.value = value + if (this.audioOutput && this.audioOutput?.mainNode) { + this.audioOutput.mainNode.gain.value = value + } } if (key === "echoCancellation") { diff --git a/packages/app/src/cores/mediartc/classes/State.ts b/packages/app/src/cores/mediartc/classes/State.ts index bc9885aed..623002e7d 100644 --- a/packages/app/src/cores/mediartc/classes/State.ts +++ b/packages/app/src/cores/mediartc/classes/State.ts @@ -1,6 +1,7 @@ import { Observable } from "@gullerya/object-observer" export interface MediaRTCStateType { + isDm: boolean isJoined: boolean isLoading: boolean isMuted: boolean @@ -22,6 +23,7 @@ export interface MediaRTCStateType { export default class MediaRTCState { static defaultState: MediaRTCStateType = { + isDm: false, isJoined: false, isLoading: false, isMuted: false, diff --git a/packages/app/src/cores/mediartc/classes/SysAudio.ts b/packages/app/src/cores/mediartc/classes/SysAudio.ts index 20aef979d..b84b589d5 100644 --- a/packages/app/src/cores/mediartc/classes/SysAudio.ts +++ b/packages/app/src/cores/mediartc/classes/SysAudio.ts @@ -121,6 +121,7 @@ export default class SysAudio { ) this.outputBus = this.outputCtx.createGain() + this.outputBus.gain.value = 1 this.pcmOutputWorklet = new AudioWorkletNode( this.outputCtx, diff --git a/packages/app/src/cores/mediartc/handlers/attachChannel.ts b/packages/app/src/cores/mediartc/handlers/attachChannel.ts new file mode 100644 index 000000000..867742414 --- /dev/null +++ b/packages/app/src/cores/mediartc/handlers/attachChannel.ts @@ -0,0 +1,95 @@ +import MediaRTC from "../mediartc.core" +import { Device } from "mediasoup-client" +import Client from "../classes/Client" + +export default async function (this: MediaRTC, data: any) { + try { + if (this.state.isJoined) { + await this.handlers.leaveChannel() + } + + this.state.isLoading = true + + // create device + this.device = await Device.factory() + + await this.self.createMicStream() + + // resume audio context + if (this.self.audioOutput.state === "suspended") { + await this.self.audioOutput.resume() + } + + // start ui + if (this.ui) { + this.ui.attach() + } + + // load device + await this.device.load({ + routerRtpCapabilities: data.rtpCapabilities, + }) + + // set all clients + for (let client of data.clients) { + this.clients.set(client.userId, new Client(this, client)) + } + + // create and setup transports + await this.handlers.createTransports() + + // start audio producer + await this.self.startMicProducer() + + // sync producers & clients mic + if (data.producers && Array.isArray(data.producers)) { + for (const producer of data.producers) { + // if is self producer, skip + if (producer.userId === app.userData._id) { + continue + } + + // add to producers + this.producers.setRemote(producer) + + const client = this.clients.get(producer.userId) + + if (client) { + // attach current client mic + if (producer.appData.mediaTag === "user-mic") { + await client.attachMic({ + producerId: producer.producerId, + userId: producer.userId, + kind: producer.kind, + appData: producer.appData, + }) + } + } + } + } + + this.state.isJoined = true + this.state.isLoading = false + this.state.connectedAt = new Date() + + this.console.log("Joined channel", data) + } catch (error) { + this.console.error(error) + this.console.error(error.stack) + + this.state.isJoined = false + this.state.isLoading = false + + if (this.ui) { + this.ui.detach() + } + + this.self.stopAll() + + app.cores.notifications.new({ + title: "Failed to join channel", + message: error.message, + type: "error", + }) + } +} diff --git a/packages/app/src/cores/mediartc/handlers/callUser.js b/packages/app/src/cores/mediartc/handlers/callUser.js index 1b36d132b..ab5b9cf0e 100644 --- a/packages/app/src/cores/mediartc/handlers/callUser.js +++ b/packages/app/src/cores/mediartc/handlers/callUser.js @@ -23,12 +23,18 @@ export default async function (userId, { alternativeSfx = false } = {}) { throw new Error("userId must be a string") } - const callInfo = await this.socket.call("call:dispatch", { + const data = await this.socket.call("call:dispatch", { userId, alternativeSfx: alternativeSfx, }) - console.log(callInfo) + this.state.isDm = true + this.state.channelId = data.channelId + this.state.channel = { + channelId: data.channelId, + _id: data.channelId, + name: userId, + } const outgoingCallAudioSrc = app.cores.sfx.soundsPool()["call_outgoing"]?._src @@ -41,11 +47,13 @@ export default async function (userId, { alternativeSfx = false } = {}) { loop: true, volume: 0.5, }) - this._outgoingCallAudio.play() + //this._outgoingCallAudio.play() } // start the timeout this._outgoingCallIgnoreTimeout = setTimeout(() => { ignoreOutgoingCall(this) }, ignoreIncomingCallTimeout) + + await this.handlers.attachChannel(data) } diff --git a/packages/app/src/cores/mediartc/handlers/createTransports.js b/packages/app/src/cores/mediartc/handlers/createTransports.js index bd295dec9..c418d0ee2 100644 --- a/packages/app/src/cores/mediartc/handlers/createTransports.js +++ b/packages/app/src/cores/mediartc/handlers/createTransports.js @@ -2,6 +2,7 @@ const sendTransportHandlers = { connect: async function ({ dtlsParameters }, callback, errback) { try { await this.socket.call("channel:connect_transport", { + isDm: this.state.isDm ?? false, transportId: this.sendTransport.id, dtlsParameters, }) @@ -19,6 +20,7 @@ const sendTransportHandlers = { ) { try { const result = await this.socket.call("channel:produce", { + isDm: this.state.isDm ?? false, transportId: this.sendTransport.id, kind, rtpParameters, @@ -54,6 +56,7 @@ const recvTransportHandlers = { connect: async function ({ dtlsParameters }, callback, errback) { try { await this.socket.call("channel:connect_transport", { + isDm: this.state.isDm ?? false, transportId: this.recvTransport.id, dtlsParameters, }) @@ -85,7 +88,12 @@ const recvTransportObserver = { export default async function () { console.debug("[webrtc] Creating new send transport") - const sendTransportInfo = await this.socket.call("channel:create_transport") + const sendTransportInfo = await this.socket.call( + "channel:create_transport", + { + isDm: this.state.isDm ?? false, + }, + ) console.debug("[webrtc] [send:transport] created", sendTransportInfo) this.sendTransport = this.device.createSendTransport({ @@ -99,7 +107,12 @@ export default async function () { }) console.debug("[webrtc] Creating new recv transport") - const recvTransportInfo = await this.socket.call("channel:create_transport") + const recvTransportInfo = await this.socket.call( + "channel:create_transport", + { + isDm: this.state.isDm ?? false, + }, + ) console.debug("[webrtc] [recv:transport] created", recvTransportInfo) this.recvTransport = this.device.createRecvTransport({ diff --git a/packages/app/src/cores/mediartc/handlers/joinChannel.ts b/packages/app/src/cores/mediartc/handlers/joinChannel.ts index beb9c578e..be2d64b2f 100644 --- a/packages/app/src/cores/mediartc/handlers/joinChannel.ts +++ b/packages/app/src/cores/mediartc/handlers/joinChannel.ts @@ -1,9 +1,5 @@ import MediaRTC from "../mediartc.core" -//@ts-ignore import GroupModel from "@models/groups" -//@ts-ignore -import Client from "../classes/Client" -import { Device } from "mediasoup-client" export default async function ( this: MediaRTC, @@ -11,15 +7,6 @@ export default async function ( channelId: string, ) { try { - if (this.state.isJoined) { - await this.handlers.leaveChannel() - } - - this.state.isLoading = true - - // create device - this.device = await Device.factory() - // fetch channel data const channelData = await GroupModel.channels.get(groupId, channelId) @@ -29,96 +16,16 @@ export default async function ( self: this, }) - await this.self.createMicStream() - - // resume audio context - if (this.self.audioOutput.state === "suspended") { - await this.self.audioOutput.resume() - } - - // start ui - if (this.ui) { - this.ui.attach() - } - const data = await this.socket.call("channel:join", channelData._id) - // dispatch sfx - app.cores.sfx.play("media_channel_join") - this.state.channel = channelData - this.state.channelId = channelData._id - - if (data.started_at) { - this.state.channel.started_at = data.started_at - } - - // load device - await this.device.load({ - routerRtpCapabilities: data.rtpCapabilities, - }) - - // set all clients - for (let client of data.clients) { - this.clients.set(client.userId, new Client(this, client)) - } - - // create and setup transports - await this.handlers.createTransports() + this.state.channelId = channelId - // start audio producer - await this.self.startMicProducer() - - // sync producers & clients mic - if (data.producers && Array.isArray(data.producers)) { - for (const producer of data.producers) { - // if is self producer, skip - if (producer.userId === app.userData._id) { - continue - } - - // add to producers - this.producers.setRemote(producer) - - const client = this.clients.get(producer.userId) - - if (client) { - // attach current client mic - if (producer.appData.mediaTag === "user-mic") { - await client.attachMic({ - producerId: producer.producerId, - userId: producer.userId, - kind: producer.kind, - appData: producer.appData, - }) - } - } - } - } - - this.state.isJoined = true - this.state.isLoading = false - this.state.connectedAt = new Date() + // dispatch sfx + app.cores.sfx.play("media_channel_join") - this.console.log("Joined channel", { - ...data, - groupId, - channelId, - clients: data.clients, - }) + await this.handlers.attachChannel(data) } catch (error: any) { - this.console.error(error) - this.console.error(error.stack) - - this.state.isJoined = false - this.state.isLoading = false - - if (this.ui) { - this.ui.detach() - } - - this.self.stopAll() - app.cores.notifications.new({ title: "Failed to join channel", message: error.message, diff --git a/packages/app/src/cores/mediartc/handlers/leaveChannel.js b/packages/app/src/cores/mediartc/handlers/leaveChannel.js deleted file mode 100644 index c2b82c7cb..000000000 --- a/packages/app/src/cores/mediartc/handlers/leaveChannel.js +++ /dev/null @@ -1,66 +0,0 @@ -import MediaRTCState from "../classes/State" - -export default async function () { - try { - if (this.ui) { - this.ui.detach() - } - - if (this.screens.size > 0) { - this.ui.detachFloatingScreens() - - for (const screen of this.screens.values()) { - screen.stop() - } - - this.screens.clear() - } - - // close transports - if (this.sendTransport && !this.sendTransport.closed) { - this.sendTransport.close() - } - if (this.recvTransport && !this.recvTransport.closed) { - this.recvTransport.close() - } - - // stop all devices - await this.self.stopAll() - - // stop all consumers - await this.consumers.stopAll() - - // destroy all clients - await this.clients.destroyAll() - - if (!this.state.isJoined) { - return null - } - - this.console.debug("Leaving channel:", { - channelId: this.state.channelId, - }) - - app.cores.sfx.play("media_channel_leave") - - // clear device - this.device = null - - // clear producers just in case - this.producers.clear() - - // reset default state - this.state = Object.assign(this.state, MediaRTCState.defaultState) - - // call socket to leave - await this.socket.call("channel:leave") - } catch (error) { - this.console.error("Error leaving channel:", error) - - app.cores.notifications.new({ - title: "Failed to leave channel", - message: error.message, - type: "error", - }) - } -} diff --git a/packages/app/src/cores/mediartc/handlers/leaveChannel.ts b/packages/app/src/cores/mediartc/handlers/leaveChannel.ts index 171744dea..4d0b0d3c4 100644 --- a/packages/app/src/cores/mediartc/handlers/leaveChannel.ts +++ b/packages/app/src/cores/mediartc/handlers/leaveChannel.ts @@ -50,11 +50,19 @@ export default async function (this: MediaRTC) { // clear producers just in case this.producers.clear() + try { + // call socket to leave + if (this.state.isDm) { + this.socket?.call("call:leave") + } else { + this.socket?.call("channel:leave") + } + } catch (error: any) { + this.console.error("Error leaving channel:", error) + } + // reset default state this.state = Object.assign(this.state, MediaRTCState.defaultState) - - // call socket to leave - await this.socket?.call("channel:leave") } catch (error: any) { this.console.error("Error leaving channel:", error) diff --git a/packages/app/src/cores/mediartc/handlers/toggleDeafen.js b/packages/app/src/cores/mediartc/handlers/toggleDeafen.js index 8158eaee0..4dd9bec79 100644 --- a/packages/app/src/cores/mediartc/handlers/toggleDeafen.js +++ b/packages/app/src/cores/mediartc/handlers/toggleDeafen.js @@ -22,10 +22,11 @@ export default async function (to) { app.cores.sfx.play("undeafen") if (this.self.sysAudio && this.self.sysAudio?.outputBus) { - this.self.sysAudio.outputBus.gain.value = 1 + this.self.sysAudio.outputBus.gain.value = + currentAudioSettings.outputGain } else { this.self.audioOutput.mainNode.gain.value = - currentAudioSettings.volume + currentAudioSettings.outputGain await this.self.audioOutput.context.resume() } } diff --git a/packages/app/src/cores/mediartc/mediartc.core.ts b/packages/app/src/cores/mediartc/mediartc.core.ts index 917a36236..e35540794 100644 --- a/packages/app/src/cores/mediartc/mediartc.core.ts +++ b/packages/app/src/cores/mediartc/mediartc.core.ts @@ -15,6 +15,7 @@ import buildWebsocketHandler from "./utils/buildWebsocketHandler" import * as Vars from "./vars" // handlers +import attachChannel from "./handlers/attachChannel" import createTransports from "./handlers/createTransports" import changeInputParams from "./handlers/changeInputParams" import changeOutputParams from "./handlers/changeOutputParams" @@ -110,6 +111,7 @@ export default class MediaRTC extends Core { } handlers: MediaRTCHandlers = { + attachChannel: attachChannel.bind(this), joinChannel: joinChannel.bind(this), leaveChannel: leaveChannel.bind(this), startCameraShare: startCameraShare.bind(this), diff --git a/packages/app/src/cores/mediartc/types.ts b/packages/app/src/cores/mediartc/types.ts index c0b9d99f9..488a0f074 100644 --- a/packages/app/src/cores/mediartc/types.ts +++ b/packages/app/src/cores/mediartc/types.ts @@ -2,6 +2,7 @@ import type MediaRTC from "./mediartc.core" import * as Vars from "./vars" export interface MediaRTCHandlers { + attachChannel: (data: any) => Promise joinChannel: (groupId: string, channelId: string) => Promise leaveChannel: () => Promise startCameraShare: () => Promise diff --git a/packages/app/src/layouts/components/modals/modal/index.jsx b/packages/app/src/layouts/components/modals/modal/index.jsx index 5be61e5df..03fcfafb5 100644 --- a/packages/app/src/layouts/components/modals/modal/index.jsx +++ b/packages/app/src/layouts/components/modals/modal/index.jsx @@ -1,4 +1,5 @@ import React from "react" +import { AnimatePresence, motion } from "motion/react" import { Modal as AntdModal } from "antd" import classnames from "classnames" @@ -30,7 +31,7 @@ class Modal extends React.Component { document.removeEventListener("keydown", this.handleEsc, false) } - close = () => { + close = async () => { this.setState({ visible: false, }) @@ -42,6 +43,12 @@ class Modal extends React.Component { }, 250) } + onCloseAnimationEnd = () => { + // if (typeof this.props.onClose === "function") { + // this.props.onClose() + // } + } + handleEsc = (e) => { if (e.key === "Escape") { if (this.escTimeout !== null) { @@ -89,30 +96,45 @@ class Modal extends React.Component { onTouchEnd={this.handleClickOutside} onMouseDown={this.handleClickOutside} /> -
- {this.props.includeCloseButton && ( -
+ {this.state.visible && ( + - -
+ {this.props.includeCloseButton && ( +
+ +
+ )} + + {React.cloneElement(this.props.children, { + close: this.close, + })} + )} - - {React.cloneElement(this.props.children, { - close: this.close, - })} -
+
) } diff --git a/packages/app/src/layouts/components/modals/modal/index.less b/packages/app/src/layouts/components/modals/modal/index.less index a68d57af1..0d03bdf88 100644 --- a/packages/app/src/layouts/components/modals/modal/index.less +++ b/packages/app/src/layouts/components/modals/modal/index.less @@ -55,13 +55,15 @@ backdrop-filter: blur(@modal_background_blur); -webkit-backdrop-filter: blur(@modal_background_blur); - .app_modal_content { + /* .app_modal_content { opacity: 1; transform: translateY(0); - } + } */ } .app_modal_content { + overflow: hidden; + overflow-y: scroll; position: relative; z-index: 1500; @@ -74,15 +76,16 @@ align-items: center; justify-content: center; - opacity: 0; - transform: translateY(100px); + /* opacity: 0; + transform: translateZ(100px); */ height: fit-content; width: 40vw; max-width: 600px; + max-height: 90vh; - transition: all 150ms ease-in-out; + //transition: all 150ms ease-in-out; .app_modal_close { position: sticky; diff --git a/packages/app/src/layouts/spaces/index.jsx b/packages/app/src/layouts/spaces/index.jsx index 4527f6bc8..630ed5c32 100644 --- a/packages/app/src/layouts/spaces/index.jsx +++ b/packages/app/src/layouts/spaces/index.jsx @@ -2,6 +2,7 @@ import React from "react" import classnames from "classnames" import { Layout } from "antd" +import LoadIcon from "@ui/LoadIcon" import BackgroundDecorator from "@components/BackgroundDecorator" import Drawer from "@layouts/components/drawer" import Modals from "@layouts/components/modals" @@ -11,19 +12,61 @@ import Sidebar from "./sidebar" import { DraggableDrawerController } from "@layouts/components/draggableDrawer" import TopBar from "@layouts/components/@mobile/topBar" import BottomBar from "@layouts/components/@mobile/bottomBar" +import OptInDialog from "../../components/Spaces/OptInDialog" import { controller as SpacesPageController, context as SpacesPageContext, } from "@contexts/WithSpaces/page" +import "./index.less" + +const useIsConnectedToMainSocket = () => { + const [connected, setConnected] = React.useState( + app.cores.api.socket()?.state.connected, + ) + + const events = { + "wsmanager:main:open": () => setConnected(true), + "wsmanager:main:reconnected": () => setConnected(true), + + "wsmanager:main:reconnecting": () => setConnected(false), + } + + React.useEffect(() => { + for (const [event, handler] of Object.entries(events)) { + app.eventBus.on(event, handler) + } + + return () => { + for (const [event, handler] of Object.entries(events)) { + app.eventBus.off(event, handler) + } + } + }, []) + + return connected +} + const SpacesLayout = (props) => { const controller = SpacesPageController() + const isMainSocketConnected = useIsConnectedToMainSocket() React.useEffect(() => { app.layout.toggleRootContainerClassname("sidebar-expanded", false) }, []) + React.useEffect(() => { + if (app.userData) { + if ( + !app.userData.flags || + !app.userData?.flags?.includes("spaces_preview") + ) { + app.layout.modal.open("optin-dialog", OptInDialog) + } + } + }, []) + return ( <> @@ -45,18 +88,19 @@ const SpacesLayout = (props) => { ...(props.contentClassnames ?? []), "content_layout", "fade-transverse-active", + "spaces-layout", )} > -
- {!controller.firstLoad && - props.children && - React.cloneElement(props.children, props)} -
+ {!isMainSocketConnected && ( +
+ + Connecting to socket +
+ )} + + {!controller.firstLoad && + props.children && + React.cloneElement(props.children, props)} {app.isMobile && } diff --git a/packages/app/src/layouts/spaces/index.less b/packages/app/src/layouts/spaces/index.less new file mode 100644 index 000000000..318514f02 --- /dev/null +++ b/packages/app/src/layouts/spaces/index.less @@ -0,0 +1,74 @@ +.spaces-layout { + display: flex; + flex-direction: column; + + width: 100%; + height: 100%; + + gap: 10px; + + .ant-splitter-panel { + overflow: hidden; + } + + &.compact { + .spaces-page__sidebar { + //max-width: 100px; + + .group-list__item { + width: fit-content; + padding: 5px; + + .group-list__item__content { + display: none; + } + } + } + + .group-list__item-other { + padding: 5px; + } + + .spaces-page__content { + width: 100%; + } + } + + &__content { + display: flex; + flex-direction: row; + + width: 100%; + height: 100%; + + padding: 10px !important; + gap: 10px; + + &__panel { + padding: 10px; + } + } +} + +.socket-indicator { + display: flex; + flex-direction: row; + + align-items: center; + + width: 100%; + + gap: 10px; + padding: 5px; + + background-color: color-mix( + in srgb, + rgba(var(--background-color-accent-values), 0.9) 80%, + rgb(66, 135, 245) 20% + ); + + border: 3px solid var(--border-color); + border-radius: 8px; + + font-family: "DM Mono"; +} diff --git a/packages/app/src/layouts/spaces/sidebar.jsx b/packages/app/src/layouts/spaces/sidebar.jsx index 5ffe4f77a..60ce06c6a 100644 --- a/packages/app/src/layouts/spaces/sidebar.jsx +++ b/packages/app/src/layouts/spaces/sidebar.jsx @@ -43,15 +43,15 @@ const SpacesSidebar = () => { collapsed: compact, })} > -
-
- app.navigation.goMain()} - className="spaces-page__sidebar__section__header__logo" - /> -
+
+ app.navigation.goMain()} + className="spaces-page__sidebar__header__logo" + /> +
+
{ return (
{ // if no channel is selected, load the first text channel (if any) if (!page.channel) { - const firstTextChannel = group.channels.find( + const firstTextChannel = group.channels.items.find( (channel) => channel.kind === "chat", ) @@ -79,7 +79,7 @@ const GroupPage = (props) => { // update the ref currentPageRef.current = page - const channelData = group.channels?.find( + const channelData = group.channels?.items.find( (_channel) => _channel._id == page.channel, ) @@ -111,9 +111,9 @@ const GroupPage = (props) => { unregisterHeaderContent: unregisterHeaderContent, }} > - + @@ -123,7 +123,7 @@ const GroupPage = (props) => { {group.loading && } @@ -143,14 +143,14 @@ const GroupPage = (props) => { -
+
diff --git a/packages/app/src/pages/spaces/group/[group_id]/index.less b/packages/app/src/pages/spaces/group/[group_id]/index.less index 27e084735..f0865431d 100644 --- a/packages/app/src/pages/spaces/group/[group_id]/index.less +++ b/packages/app/src/pages/spaces/group/[group_id]/index.less @@ -4,6 +4,8 @@ overflow: hidden; + height: 100%; + //padding: 10px; .rtc-vc-card { @@ -11,4 +13,54 @@ width: 100%; background-color: var(--backgroundColorAccent); } + + &__panel { + overflow: hidden; + + display: flex; + flex-direction: column; + + width: 100%; + min-width: 270px; + + gap: 10px; + padding: 10px !important; + } +} + +.ant-splitter-bar-collapse-bar { + padding: 10px 13px; +} + +.ant-splitter-panel.ant-splitter-panel-hidden.group-page__rightbar { + padding: 0px !important; +} + +.group-page__rightbar { + overflow: hidden; + + position: relative; + display: flex; + flex-direction: column; + + padding: 10px !important; + + align-items: center; + + transition: flex-basis 150ms ease-in-out; + + gap: 10px; + + &__attached { + margin-top: auto; + bottom: 0; + + display: flex; + flex-direction: column; + + width: 100%; + height: fit-content; + + gap: 10px; + } } diff --git a/packages/app/src/pages/spaces/index.less b/packages/app/src/pages/spaces/index.less index 0dae8f7e9..3059f6300 100755 --- a/packages/app/src/pages/spaces/index.less +++ b/packages/app/src/pages/spaces/index.less @@ -1,107 +1,5 @@ @import "@styles/vars.less"; -.spaces-page { - display: flex; - flex-direction: row; - - width: 100%; - height: 100%; - - //gap: 10px; - - .ant-splitter-panel { - overflow: hidden; - } - - &.compact { - .spaces-page__sidebar { - //max-width: 100px; - - .group-list__item { - width: fit-content; - padding: 5px; - - .group-list__item__content { - display: none; - } - } - } - - .group-list__item-other { - padding: 5px; - } - - .spaces-page__content { - width: 100%; - } - } - - &__content { - display: flex; - flex-direction: row; - - width: 100%; - height: 100%; - - padding: 10px !important; - gap: 10px; - - &__panel { - padding: 10px; - } - } -} - -.spaces-page__panel { - display: flex; - flex-direction: column; - - /* align-items: center; */ - - width: 100%; - gap: 10px; - - padding: 10px !important; - min-width: 270px; - - overflow: hidden; -} - -.ant-splitter-panel.ant-splitter-panel-hidden.spaces-page__rightbar { - padding: 0px !important; -} - -.ant-splitter-bar-collapse-bar { - padding: 10px 13px; -} - -.spaces-page__rightbar { - position: relative; - display: flex; - flex-direction: column; - - padding: 10px !important; - - align-items: center; - - transition: all 150ms ease-in-out; - - gap: 10px; - - &__attached { - margin-top: auto; - bottom: 0; - - display: flex; - flex-direction: column; - - width: 100%; - height: fit-content; - - gap: 10px; - } -} - .group-list__item-other { display: flex; flex-direction: row; diff --git a/packages/app/src/ui/Button.jsx b/packages/app/src/ui/Button.jsx index fd3a5717e..8c7543c6d 100644 --- a/packages/app/src/ui/Button.jsx +++ b/packages/app/src/ui/Button.jsx @@ -2,8 +2,7 @@ import React from "react" import PropTypes from "prop-types" import classnames from "classnames" -import UseAnimations from "react-useanimations" -import loadingAnim from "react-useanimations/lib/loading" +import LoadIcon from "./LoadIcon" import "./Button.less" @@ -38,18 +37,7 @@ const Button = ({ > {loading && (
- { - return ( -
- ) - }} - /> +
)} diff --git a/packages/app/src/ui/LoadIcon.jsx b/packages/app/src/ui/LoadIcon.jsx new file mode 100644 index 000000000..eb58ee175 --- /dev/null +++ b/packages/app/src/ui/LoadIcon.jsx @@ -0,0 +1,23 @@ +import UseAnimations from "react-useanimations" +import loadingAnim from "react-useanimations/lib/loading" + +import "./LoadIcon.less" + +const LoadIcon = () => { + return ( + { + return ( +
+ ) + }} + /> + ) +} + +export default LoadIcon diff --git a/packages/app/src/ui/LoadIcon.less b/packages/app/src/ui/LoadIcon.less new file mode 100644 index 000000000..1abb994f9 --- /dev/null +++ b/packages/app/src/ui/LoadIcon.less @@ -0,0 +1,17 @@ +.load-icon-spinner { + display: flex; + flex-direction: row; + + align-items: center; + justify-content: center; + + width: 100%; + height: 100%; + + width: 1.2em; + height: 1.2em; + + svg { + stroke-width: 2px; + } +} diff --git a/packages/app/tsconfig.json b/packages/app/tsconfig.json index e64937461..a5eb237b7 100644 --- a/packages/app/tsconfig.json +++ b/packages/app/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "target": "ES2022", + "target": "ES2023", "module": "ESNext", - "lib": ["ES2022", "DOM", "DOM.Iterable"], + "lib": ["ES2023", "DOM", "DOM.Iterable"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, @@ -19,9 +19,22 @@ "jsx": "preserve", "baseUrl": ".", "paths": { - "@models/*": ["../../models/*"], - "@components/*": ["../../components/*"], - "@utils/*": ["../../utils/*"], + "@/*": ["src/*"], + "@config/*": ["config/*"], + + "@ui/*": ["src/ui/*"], + "@cores/*": ["src/cores/*"], + "@pages/*": ["src/pages/*"], + "@styles/*": ["src/styles/*"], + "@components/*": ["src/components/*"], + "@contexts/*": ["src/contexts/*"], + "@utils/*": ["src/utils/*"], + "@layouts/*": ["src/layouts/*"], + "@hooks/*": ["src/hooks/*"], + "@classes/*": ["src/classes/*"], + "@models/*": ["../../comty.js/src/models/*"], + + "comty.js/*": ["../../comty.js/src/*"], "vessel/*": ["../../vessel/src/*"], }, }, diff --git a/packages/app/vite.config.js b/packages/app/vite.config.js index 44a927aa4..a478a42ee 100755 --- a/packages/app/vite.config.js +++ b/packages/app/vite.config.js @@ -1,11 +1,10 @@ +import { defineConfig } from "vite" +import react from "@vitejs/plugin-react" import path from "node:path" import fs from "node:fs" import aliases from "./aliases" -import { defineConfig } from "vite" -import react from "@vitejs/plugin-react" - const sslDirPath = path.resolve(__dirname, "../../", ".ssl") const config = { @@ -23,6 +22,7 @@ const config = { }, headers: { "Strict-Transport-Security": `max-age=31536000`, + "Access-Control-Allow-Origin": "*", }, proxy: { "/api": { @@ -46,7 +46,7 @@ const config = { }, }, esbuild: { - target: "es2022", + target: "es2023", }, optimizeDeps: { include: ["src/cores/**/*.core.js"], diff --git a/packages/desktop/addons/sysaudio b/packages/desktop/addons/sysaudio index 338ed903a..948c26899 160000 --- a/packages/desktop/addons/sysaudio +++ b/packages/desktop/addons/sysaudio @@ -1 +1 @@ -Subproject commit 338ed903a8160d7bc011e3322575f1b07b48e1af +Subproject commit 948c26899798c3b12833a86f7c2453bf083121f9 diff --git a/packages/desktop/package-lock.json b/packages/desktop/package-lock.json index 49ddc5227..a09d88ddf 100644 --- a/packages/desktop/package-lock.json +++ b/packages/desktop/package-lock.json @@ -1,24 +1,21 @@ { "name": "comty-desktop", - "version": "0.6.0", + "version": "0.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "comty-desktop", - "version": "0.6.0", + "version": "0.9.0", "hasInstallScript": true, "license": "MIT", "dependencies": { - "cross-env": "^10.0.0", "electron-store": "^10.1.0", "mime": "^4.1.0", - "paclient": "^0.0.2", - "radix-router": "^3.0.1", - "router": "^2.2.0" + "radix-router": "^3.0.1" }, "devDependencies": { - "electron": "^39.6.0", + "electron": "^39.8.6", "electron-builder": "^26.8.1", "electron-devtools-installer": "^4.0.0" } @@ -830,12 +827,6 @@ "node": ">= 10.0.0" } }, - "node_modules/@epic-web/invariant": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", - "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", - "license": "MIT" - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1693,18 +1684,41 @@ "node": ">=12" } }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/cacache/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, + "extraneous": true, "license": "MIT" }, "node_modules/cacache/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, + "extraneous": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -1715,7 +1729,7 @@ "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, + "extraneous": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -1728,14 +1742,14 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, + "extraneous": true, "license": "ISC" }, "node_modules/cacache/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, + "extraneous": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.2" @@ -2052,27 +2066,11 @@ "license": "MIT", "optional": true }, - "node_modules/cross-env": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz", - "integrity": "sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==", - "license": "MIT", - "dependencies": { - "@epic-web/invariant": "^1.0.0", - "cross-spawn": "^7.0.6" - }, - "bin": { - "cross-env": "dist/bin/cross-env.js", - "cross-env-shell": "dist/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=20" - } - }, "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", @@ -2102,6 +2100,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2215,15 +2214,6 @@ "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_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -2290,7 +2280,6 @@ "integrity": "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "app-builder-lib": "26.8.1", "builder-util": "26.8.1", @@ -2488,9 +2477,9 @@ } }, "node_modules/electron": { - "version": "39.6.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-39.6.0.tgz", - "integrity": "sha512-KQK3sJ6JCyymY3HQxV0N/bVBQwKQETRW0N/+OYcrL9H6tZhpmTSaZY3qSxcruWrPIuouvoiP3Vk/JKUpw05ZIw==", + "version": "39.8.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-39.8.6.tgz", + "integrity": "sha512-uWX6Jh5LmwL13VwOSKBjebI+ck+03GOwc8V2Sgbmr9pJVJ/cHfli/PkjXuRDr+hq+SLHQuT9mGHSIfScebApRA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3521,12 +3510,6 @@ "node": ">=8" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -3564,6 +3547,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, "license": "ISC" }, "node_modules/jackspeak": { @@ -4018,6 +4002,7 @@ "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/negotiator": { @@ -4199,14 +4184,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/paclient": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/paclient/-/paclient-0.0.2.tgz", - "integrity": "sha512-bbTT2Jg8Jp6NN8YgFO71TrKgFQgQLYdSC+DtNdrdfrxA0MOqVXJSmAUb90LliTo1HtLwbGITy8/IHXBEn9swnQ==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -4214,15 +4191,6 @@ "dev": true, "license": "(MIT AND Zlib)" }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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", @@ -4237,6 +4205,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4266,16 +4235,6 @@ "dev": true, "license": "ISC" }, - "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/pe-library": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", @@ -4587,22 +4546,6 @@ "node": ">=8.0" } }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4697,6 +4640,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -4709,6 +4653,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5214,6 +5159,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" diff --git a/packages/desktop/package.json b/packages/desktop/package.json index ddc54523c..8f97bca49 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -4,7 +4,7 @@ "description": "Official desktop client for Comty", "appName": "Comty", "processName": "comty-desktop", - "version": "0.8.1", + "version": "0.9.0", "license": "MIT", "type": "module", "main": "./src/boot.js", @@ -21,7 +21,7 @@ "radix-router": "^3.0.1" }, "devDependencies": { - "electron": "^39.6.0", + "electron": "^39.8.6", "electron-builder": "^26.8.1", "electron-devtools-installer": "^4.0.0" } diff --git a/packages/desktop/src/classes/SysAudio/index.js b/packages/desktop/src/classes/SysAudio/index.js index b026b1aa5..870d95d6f 100644 --- a/packages/desktop/src/classes/SysAudio/index.js +++ b/packages/desktop/src/classes/SysAudio/index.js @@ -9,6 +9,16 @@ export default class SysAudio { constructor(main) { this.main = main + sysaudio.initialize({ + excluded_pid: process.pid, + node_name: this.main.constructor.isDev + ? "comty-sysaudio-dev" + : "comty-sysaudio", + device_app_id: "comty.desktop", + device_app_name: this.main.constructor.isDev ? "ComtyDev" : "Comty", + device_app_icon_name: "comty", + }) + ipcMain.handle("sysaudio:startCapture", this.startCapture) ipcMain.handle("sysaudio:stopCapture", this.stopCapture) ipcMain.on("sysaudio:output", this.sendToOutput) diff --git a/packages/desktop/src/main.js b/packages/desktop/src/main.js index 8cebef53e..270958444 100644 --- a/packages/desktop/src/main.js +++ b/packages/desktop/src/main.js @@ -35,8 +35,11 @@ export default class Main { if (Main.isDev) { this.app.setName(pkgjson.processName + "_dev") + this.app.setPath("userData", this.app.getPath("userData") + "_dev") + this.appName = pkgjson.appName + "_dev" } else { this.app.setName(pkgjson.processName) + this.appName = pkgjson.appName } flags(this.app) diff --git a/packages/server/classes/AuthToken/index.js b/packages/server/classes/AuthToken/index.js index 33efbc540..70d313476 100644 --- a/packages/server/classes/AuthToken/index.js +++ b/packages/server/classes/AuthToken/index.js @@ -1,11 +1,8 @@ import jwt from "jsonwebtoken" import { User } from "@db_models" +import AuthSessionModel from "@db/auth_session" export default class AuthToken { - static get SessionModel() { - return global.scylla.model("auth_session") - } - static get authStrategy() { return { expiresIn: process.env.JWT_EXPIRES_IN ?? "1h", @@ -91,9 +88,10 @@ export default class AuthToken { return result } - const session = await AuthToken.SessionModel.findOneAsync( + const session = await AuthSessionModel.findOne( { _id: validation.data.session_id, + user_id: validation.data.user_id, }, { raw: true }, ) diff --git a/packages/server/classes/ScyllaDb/index.js b/packages/server/classes/ScyllaDb/index.js deleted file mode 100644 index a78d2b6c9..000000000 --- a/packages/server/classes/ScyllaDb/index.js +++ /dev/null @@ -1,78 +0,0 @@ -import fs from "node:fs" -import path from "node:path" - -import ExpressCassandra from "express-cassandra" - -const { SCYLLA_CONTACT_POINTS, SCYLLA_LOCAL_DATA_CENTER, SCYLLA_KEYSPACE } = - process.env - -export default class ScyllaDb { - constructor(config = {}) { - this.config = { - modelsPath: path.resolve(__dirname, "../../scylla_db_models"), - contactPoints: SCYLLA_CONTACT_POINTS - ? SCYLLA_CONTACT_POINTS.split(",") - : ["127.0.0.1"], - localDataCenter: SCYLLA_LOCAL_DATA_CENTER ?? "datacenter1", - keyspace: SCYLLA_KEYSPACE ?? "comty", - port: 9042, - ...config, - } - } - - client = null - - async initialize() { - this.client = ExpressCassandra.createClient({ - clientOptions: { - contactPoints: this.config.contactPoints, - localDataCenter: this.config.localDataCenter, - protocolOptions: { port: this.config.port, version: 4 }, - keyspace: this.config.keyspace, - queryOptions: { - consistency: ExpressCassandra.consistencies.one, - }, - socketOptions: { readTimeout: 60000 }, - }, - ormOptions: { - defaultReplicationStrategy: { - class: "SimpleStrategy", - replication_factor: 1, - }, - migration: "alter", - }, - }) - - await this.loadModels() - - console.log("ScyllaDB client initialized") - } - - async loadModels() { - let modelFiles = await fs.promises.readdir(this.config.modelsPath) - - modelFiles = modelFiles.filter((file) => file.endsWith(".js")) - - for await (const file of modelFiles) { - const modelName = file.replace(".js", "") - const modelPath = path.join(this.config.modelsPath, file) - - try { - let modelModule = await import(modelPath) - - modelModule = modelModule.default - - this.client.loadSchema(modelName, modelModule) - - await this.client.instance[modelName].syncDBAsync() - } catch (error) { - console.error(`Failed to load model [${modelName}]:`) - throw error - } - } - } - - model(name) { - return this.client.instance[name] - } -} diff --git a/packages/server/classes/Spaces/GroupChannels/index.js b/packages/server/classes/Spaces/GroupChannels/index.js index 3f603a5c2..3c698899a 100644 --- a/packages/server/classes/Spaces/GroupChannels/index.js +++ b/packages/server/classes/Spaces/GroupChannels/index.js @@ -5,13 +5,16 @@ import updateMethod from "./methods/update" import deleteMethod from "./methods/delete" import orderMethod from "./methods/order" +import GroupChannelsModel from "@db/group_channels" +import ChannelOrdersModel from "@db/channel_orders" + export default class GroupChannels { static get model() { - return global.scylla.model("group_channels") + return GroupChannelsModel } static get orderModel() { - return global.scylla.model("channel_orders") + return ChannelOrdersModel } static kinds = { diff --git a/packages/server/classes/Spaces/GroupChannels/methods/create.js b/packages/server/classes/Spaces/GroupChannels/methods/create.js index 3379c7824..d7ae922ae 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/create.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/create.js @@ -34,9 +34,10 @@ export default async function (group, payload, user_id) { } const channelId = global.snowflake.nextId().toString() - const created_at = new Date().toISOString() + const created_at = new Date() - const channel = new this.model({ + const channel = this.model.obj({ + __v: 0, _id: channelId, group_id: group._id, kind: payload.kind, @@ -46,7 +47,19 @@ export default async function (group, payload, user_id) { created_at: created_at, }) - await channel.saveAsync() + await channel.save() - return channel.toJSON() + if (global.websockets) { + try { + global.websockets.senders.toTopic( + `group:${group._id}`, + `group:${group._id}:channel:created`, + channel.toRaw(), + ) + } catch (error) { + console.error("Failed to send event to group topic", error) + } + } + + return channel.toRaw() } diff --git a/packages/server/classes/Spaces/GroupChannels/methods/delete.js b/packages/server/classes/Spaces/GroupChannels/methods/delete.js index 1a887ece9..08fdff9f4 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/delete.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/delete.js @@ -30,7 +30,19 @@ export default async function (group, channel_id, user_id) { } } - await channel.deleteAsync() + await channel.delete() + + if (global.websockets) { + try { + global.websockets.senders.toTopic( + `group:${group._id}`, + `group:${group._id}:channel:deleted`, + channel.toRaw(), + ) + } catch (error) { + console.error("Failed to send event to group topic", error) + } + } return channel } diff --git a/packages/server/classes/Spaces/GroupChannels/methods/get.js b/packages/server/classes/Spaces/GroupChannels/methods/get.js index a985c0267..04a687712 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/get.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/get.js @@ -1,4 +1,5 @@ import GroupPermissions from "@shared-classes/Spaces/GroupPermissions" +import GroupChannelsModel from "@db/group_channels" export default async function (group, channel_id, user_id) { if (typeof group !== "object") { @@ -9,7 +10,7 @@ export default async function (group, channel_id, user_id) { throw new OperationError(400, "channel_id must be a string") } - const channel = await this.model.findOneAsync({ + const channel = await GroupChannelsModel.findOne({ group_id: group._id, _id: channel_id, }) diff --git a/packages/server/classes/Spaces/GroupChannels/methods/getAllByGroupId.js b/packages/server/classes/Spaces/GroupChannels/methods/getAllByGroupId.js index b99b04676..5106834e1 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/getAllByGroupId.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/getAllByGroupId.js @@ -21,7 +21,7 @@ export default async function (group, user_id) { } } - let channels = await this.model.findAsync({ + let channels = await this.model.find({ group_id: group._id, }) diff --git a/packages/server/classes/Spaces/GroupChannels/methods/order.js b/packages/server/classes/Spaces/GroupChannels/methods/order.js index 1f50fc74f..0fb6993ae 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/order.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/order.js @@ -24,12 +24,24 @@ export default async function (group, order_ids, user_id) { } } - let order = await this.orderModel.updateAsync( + let order = await this.orderModel.update( { group_id: group._id }, { order: order_ids, }, ) + if (global.websockets) { + try { + global.websockets.senders.toTopic( + `group:${group._id}`, + `group:${group._id}:channels:ordered`, + order_ids, + ) + } catch (error) { + console.error("Failed to send event to group topic", error) + } + } + return order } diff --git a/packages/server/classes/Spaces/GroupChannels/methods/update.js b/packages/server/classes/Spaces/GroupChannels/methods/update.js index a008c2a56..931efc4f2 100644 --- a/packages/server/classes/Spaces/GroupChannels/methods/update.js +++ b/packages/server/classes/Spaces/GroupChannels/methods/update.js @@ -42,7 +42,19 @@ export default async function (group, channel_id, payload, user_id) { channel.params = payload.params } - await channel.saveAsync() + await channel.save() + + if (global.websockets) { + try { + global.websockets.senders.toTopic( + `group:${group._id}`, + `group:${group._id}:channel:updated`, + channel.toRaw(), + ) + } catch (error) { + console.error("Failed to send event to group topic", error) + } + } return channel } diff --git a/packages/server/classes/Spaces/GroupInvites/index.js b/packages/server/classes/Spaces/GroupInvites/index.js index 47ab7ea13..9f47aef4f 100644 --- a/packages/server/classes/Spaces/GroupInvites/index.js +++ b/packages/server/classes/Spaces/GroupInvites/index.js @@ -3,9 +3,11 @@ import getAllByGroupMethod from "./methods/getAllByGroup" import createMethod from "./methods/create" import deleteMethod from "./methods/delete" +import GroupInviteKeyModel from "@db/group_invite_key" + export default class GroupInvites { static get model() { - return global.scylla.model("group_invite_key") + return GroupInviteKeyModel } static get = getMethod.bind(this) diff --git a/packages/server/classes/Spaces/GroupInvites/methods/create.js b/packages/server/classes/Spaces/GroupInvites/methods/create.js index e93ba77a6..295755d39 100644 --- a/packages/server/classes/Spaces/GroupInvites/methods/create.js +++ b/packages/server/classes/Spaces/GroupInvites/methods/create.js @@ -11,7 +11,7 @@ export default async function (group, payload) { throw new OperationError(400, "issuer_user_id must be provided") } - const invite = new this.model({ + const invite = this.model.obj({ group_id: group._id.toString(), key: nanoid(), issuer_user_id: payload.issuer_user_id, @@ -19,7 +19,7 @@ export default async function (group, payload) { created_at: new Date().toISOString(), }) - await invite.saveAsync() + await invite.save() - return invite.toJSON() + return invite.toRaw() } diff --git a/packages/server/classes/Spaces/GroupInvites/methods/delete.js b/packages/server/classes/Spaces/GroupInvites/methods/delete.js index 724da1665..5ad7a2228 100644 --- a/packages/server/classes/Spaces/GroupInvites/methods/delete.js +++ b/packages/server/classes/Spaces/GroupInvites/methods/delete.js @@ -7,7 +7,7 @@ export default async function (group, key) { throw new OperationError(400, "key must be provided") } - const invite = await this.model.findOneAsync({ + const invite = await this.model.findOne({ group_id: group._id.toString(), key: key, }) @@ -16,7 +16,7 @@ export default async function (group, key) { throw new OperationError(404, "Invite not found") } - await invite.deleteAsync() + await invite.delete() - return invite.toJSON() + return invite.toRaw() } diff --git a/packages/server/classes/Spaces/GroupInvites/methods/get.js b/packages/server/classes/Spaces/GroupInvites/methods/get.js index 14067578c..257c25f7b 100644 --- a/packages/server/classes/Spaces/GroupInvites/methods/get.js +++ b/packages/server/classes/Spaces/GroupInvites/methods/get.js @@ -7,7 +7,7 @@ export default async function (group, key, { raw = true } = {}) { throw new OperationError(400, "key must be provided") } - const invite = await this.model.findOneAsync({ + const invite = await this.model.findOne({ group_id: group._id.toString(), key: key, }) @@ -17,7 +17,7 @@ export default async function (group, key, { raw = true } = {}) { } if (raw === true) { - return invite.toJSON() + return invite.toRaw() } return invite diff --git a/packages/server/classes/Spaces/GroupInvites/methods/getAllByGroup.js b/packages/server/classes/Spaces/GroupInvites/methods/getAllByGroup.js index 39c1aa65f..6c70020c1 100644 --- a/packages/server/classes/Spaces/GroupInvites/methods/getAllByGroup.js +++ b/packages/server/classes/Spaces/GroupInvites/methods/getAllByGroup.js @@ -3,7 +3,7 @@ export default async function (group) { throw new OperationError(400, "group must be provided") } - const invites = await this.model.findAsync( + const invites = await this.model.find( { group_id: group._id.toString(), }, diff --git a/packages/server/classes/Spaces/GroupMemberships/index.js b/packages/server/classes/Spaces/GroupMemberships/index.js index fc8249124..b5848a471 100644 --- a/packages/server/classes/Spaces/GroupMemberships/index.js +++ b/packages/server/classes/Spaces/GroupMemberships/index.js @@ -6,9 +6,19 @@ import getByUserIdMethod from "./methods/getByUserId" import getTotalMembersByGroupIdMethod from "./methods/getTotalMembersByGroupId" import isUserIdOnMembersMethod from "./methods/isUserIdOnMembers" +import GroupMembershipsModel from "@db/group_memberships" +import GroupMembershipsRefModel from "@db/group_memberships_ref" +import GroupMembershipsCounterModel from "@db/group_memberships_counter" + export default class GroupMemberships { static get model() { - return global.scylla.model("group_memberships") + return GroupMembershipsModel + } + static get modelRef() { + return GroupMembershipsRefModel + } + static get modelCounter() { + return GroupMembershipsCounterModel } static get = getMethod.bind(this) diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/create.js b/packages/server/classes/Spaces/GroupMemberships/methods/create.js index 3f772f76b..ef0e9c9d4 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/create.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/create.js @@ -1,3 +1,6 @@ +// @ts-ignore +import { q } from "@ragestudio/scylla-odm/driver/mapping/q" + export default async function (group_id, user_id) { if (typeof group_id !== "string") { throw new OperationError(400, "group_id must be provided") @@ -13,34 +16,68 @@ export default async function (group_id, user_id) { } const _id = global.snowflake.nextId().toString() - const created_at = new Date().toISOString() + const created_at = new Date() - const membership = new this.model({ + const membership = this.model.obj({ _id: _id, user_id: user_id, group_id: group_id, created_at: created_at, }) - await membership.saveAsync() + await membership.save() + + // update the membership ref + const groupRef = this.modelRef.obj({ + group_id: group_id, + user_id: user_id, + membership_id: membership._id, + created_at: created_at, + }) + + await groupRef.save() + + // increase the counter + await this.modelCounter.update({ + group_id: group_id, + counter: q.incr(1), + }) + + if (global.websockets) { + const eventPayload = { + membership_id: membership._id, + user_id: user_id, + group_id: group_id, + } + + if (membership.user_id) { + try { + global.websockets.senders.toUserId( + user_id, + "groups:membership:created", + eventPayload, + ) + } catch (error) { + console.error( + "Failed to send (groups:membership:created) to user", + error, + ) + } + } - if (global.websockets && membership.user_id) { try { - global.websockets.senders.toUserId( - user_id, - "groups:membership:created", - { - membership_id: membership._id, - group_id: group_id, - }, + global.websockets.senders.toTopic( + `group:${group_id}`, + `group:${group_id}:membership:created`, + eventPayload, ) } catch (error) { console.error( - "Failed to send (groups:membership:created) to user", + "Failed to send (groups:membership:created) to group topic", error, ) } } - return membership.toJSON() + return membership.toRaw() } diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/delete.js b/packages/server/classes/Spaces/GroupMemberships/methods/delete.js index 10723e201..3e21a60b1 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/delete.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/delete.js @@ -1,12 +1,20 @@ import Groups from "@shared-classes/Spaces/Groups" -export default async function (membership_id, group_id, group) { +import { q } from "@ragestudio/scylla-odm/driver/mapping/q" + +export default async function (user_id, membership_id, group_id, group) { + if (typeof user_id !== "string") { + throw new OperationError(400, "user_id must be a string") + } + if (typeof membership_id !== "string") { + throw new OperationError(400, "membership_id must be a string") + } if (typeof group_id !== "string") { throw new OperationError(400, "group_id must be a string") } if (!group) { - group = await Groups.model.findOneAsync({ + group = await Groups.model.findOne({ _id: group_id, }) } @@ -15,26 +23,60 @@ export default async function (membership_id, group_id, group) { throw new OperationError(404, "Group not found") } - const membership = await this.model.findOneAsync({ + let membership = await this.model.findOne({ + user_id: user_id, group_id: group_id, _id: membership_id, }) - await membership.deleteAsync() + if (!membership) { + throw new OperationError(404, "Membership not exist for this group") + } + + await membership.delete() + + await this.modelRef.delete({ + group_id: group_id, + user_id: user_id, + }) + + // decrease the counter + await this.modelCounter.update({ + group_id: group_id, + counter: q.decr(1), + }) + + if (global.websockets) { + const eventPayload = { + membership_id: membership._id, + user_id: membership.user_id, + group_id: group_id, + } + + if (membership.user_id) { + try { + global.websockets.senders.toUserId( + membership.user_id, + "groups:membership:deleted", + eventPayload, + ) + } catch (error) { + console.error( + "Failed to send (groups:membership:deleted) to user", + error, + ) + } + } - if (global.websockets && membership.user_id) { try { - global.websockets.senders.toUserId( - membership.user_id, - "groups:membership:deleted", - { - membership_id: membership_id, - group_id: group_id, - }, + global.websockets.senders.toTopic( + `group:${group_id}`, + `group:${group_id}:membership:deleted`, + eventPayload, ) } catch (error) { console.error( - "Failed to send (groups:membership:deleted) to user", + "Failed to send (groups:membership:deleted) to group topic", error, ) } diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/get.js b/packages/server/classes/Spaces/GroupMemberships/methods/get.js index 9c36eb91c..4857885b2 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/get.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/get.js @@ -1,4 +1,8 @@ -export default async function (group_id, membership_id) { +export default async function (group_id, user_id, membership_id) { + if (typeof user_id !== "string") { + throw new OperationError(400, "user_id must be a string") + } + if (typeof group_id !== "string") { throw new OperationError(400, "group_id must be a string") } @@ -7,7 +11,8 @@ export default async function (group_id, membership_id) { throw new OperationError(400, "membership_id must be a string") } - return await this.model.findOneAsync({ + return await this.model.findOne({ + user_id: user_id, group_id: group_id, _id: membership_id, }) diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/getByGroupId.js b/packages/server/classes/Spaces/GroupMemberships/methods/getByGroupId.js index 9760acff2..e605734f5 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/getByGroupId.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/getByGroupId.js @@ -6,9 +6,10 @@ export default async function (group_id, { limit, offset } = {}) { const query = { group_id: group_id, } + const options = {} if (limit) { - query.$limit = parseInt(limit) + options.limit = parseInt(limit) } if (offset) { @@ -17,7 +18,16 @@ export default async function (group_id, { limit, offset } = {}) { } } - const memberships = await this.model.findAsync(query) + const membershipsRef = await this.modelRef.find(query, limit) + + const users_ids = membershipsRef.map((ref) => ref.user_id) + + const memberships = await this.model.find({ + user_id: { + $in: users_ids, + }, + group_id: group_id, + }) return memberships } diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/getByUserId.js b/packages/server/classes/Spaces/GroupMemberships/methods/getByUserId.js index 173fde19e..87f09382e 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/getByUserId.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/getByUserId.js @@ -6,9 +6,10 @@ export default async function (user_id, { limit, offset } = {}) { const query = { user_id: user_id, } + const options = {} if (limit) { - query.$limit = parseInt(limit) + options.limit = parseInt(limit) } if (offset) { @@ -17,7 +18,7 @@ export default async function (user_id, { limit, offset } = {}) { } } - const memberships = await this.model.findAsync(query) + const memberships = await this.model.find(query, options) return memberships } diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/getTotalMembersByGroupId.js b/packages/server/classes/Spaces/GroupMemberships/methods/getTotalMembersByGroupId.js index 5ebd98ac5..c90c44dc1 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/getTotalMembersByGroupId.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/getTotalMembersByGroupId.js @@ -3,9 +3,13 @@ export default async function (group_id) { throw new OperationError(400, "group_id must be a string") } - const memberships = await this.model.findAsync({ + const reg = await this.modelCounter.findOne({ group_id: group_id, }) - return memberships.length + if (reg?.counter) { + return parseInt(reg.counter) + } + + return 0 } diff --git a/packages/server/classes/Spaces/GroupMemberships/methods/isUserIdOnMembers.js b/packages/server/classes/Spaces/GroupMemberships/methods/isUserIdOnMembers.js index bd3c6eb48..aac7421c9 100644 --- a/packages/server/classes/Spaces/GroupMemberships/methods/isUserIdOnMembers.js +++ b/packages/server/classes/Spaces/GroupMemberships/methods/isUserIdOnMembers.js @@ -1,5 +1,5 @@ export default async function (user_id, group_id) { - const membership = await this.model.findOneAsync( + const membership = await this.model.find( { user_id: user_id, group_id: group_id, @@ -9,5 +9,5 @@ export default async function (user_id, group_id) { }, ) - return !!membership + return membership.length !== 0 } diff --git a/packages/server/classes/Spaces/GroupPermissions/methods/canPerformAction.js b/packages/server/classes/Spaces/GroupPermissions/methods/canPerformAction.js index 173a5aea6..77ec7287f 100644 --- a/packages/server/classes/Spaces/GroupPermissions/methods/canPerformAction.js +++ b/packages/server/classes/Spaces/GroupPermissions/methods/canPerformAction.js @@ -25,8 +25,9 @@ export default async function (user_id, group, action) { } // get the user membership - const membership = await GroupMemberships.model.findOneAsync( + let membership = await GroupMemberships.model.find( { + group_id: group._id, user_id: user_id, }, { @@ -34,6 +35,8 @@ export default async function (user_id, group, action) { }, ) + membership = membership[0] + if (!membership) { throw new OperationError(404, "Membership not found") } diff --git a/packages/server/classes/Spaces/GroupRoles/index.js b/packages/server/classes/Spaces/GroupRoles/index.js index 8bb102e27..ba8e66c6d 100644 --- a/packages/server/classes/Spaces/GroupRoles/index.js +++ b/packages/server/classes/Spaces/GroupRoles/index.js @@ -1,14 +1,12 @@ -export default class GroupRoles { - static get model() { - return global.scylla.model("group_roles") - } +import GroupRolesModel from "@db/group_roles" +export default class GroupRoles { static async getByGroupId(group_id) { if (typeof group_id !== "string") { throw new OperationError(400, "group_id must be a string") } - const roles = await this.model.findAsync( + const roles = await GroupRolesModel.find( { group_id: group_id, }, diff --git a/packages/server/classes/Spaces/Groups/index.js b/packages/server/classes/Spaces/Groups/index.js index 2c3628223..21df39bc4 100644 --- a/packages/server/classes/Spaces/Groups/index.js +++ b/packages/server/classes/Spaces/Groups/index.js @@ -7,15 +7,19 @@ import deleteMethod from "./methods/delete" import canUserIdReachMethod from "./methods/canUserIdReach" import sortMerthod from "./methods/sort" +import GroupsModel from "@db/groups" +import GroupsUserOrdersModel from "@db/groups_user_orders" +import GroupInviteKeyModel from "@db/group_invite_key" + export default class Groups { static get model() { - return global.scylla.model("groups") + return GroupsModel } static get sortModel() { - return global.scylla.model("groups_user_orders") + return GroupsUserOrdersModel } static get inviteKeyModel() { - return global.scylla.model("group_invite_key") + return GroupInviteKeyModel } static get = getMethod.bind(this) diff --git a/packages/server/classes/Spaces/Groups/methods/create.js b/packages/server/classes/Spaces/Groups/methods/create.js index 267203304..68190655b 100644 --- a/packages/server/classes/Spaces/Groups/methods/create.js +++ b/packages/server/classes/Spaces/Groups/methods/create.js @@ -7,9 +7,10 @@ export default async function (payload) { } const groupId = global.snowflake.nextId().toString() - const created_at = new Date().toISOString() + const created_at = new Date() - const group = new this.model({ + const group = this.model.obj({ + __v: 0, _id: groupId, name: payload.name, description: payload.description, @@ -20,7 +21,7 @@ export default async function (payload) { created_at: created_at, }) - await group.saveAsync() + await group.save() // create the membership await GroupMemberships.create(groupId, payload.owner_user_id) @@ -35,5 +36,5 @@ export default async function (payload) { payload.owner_user_id, ) - return group.toJSON() + return group.toRaw() } diff --git a/packages/server/classes/Spaces/Groups/methods/createInviteKey.js b/packages/server/classes/Spaces/Groups/methods/createInviteKey.js index e867b9e29..596b490cc 100644 --- a/packages/server/classes/Spaces/Groups/methods/createInviteKey.js +++ b/packages/server/classes/Spaces/Groups/methods/createInviteKey.js @@ -18,7 +18,7 @@ export default async function ( ) } - const obj = new this.inviteKeyModel({ + const obj = this.inviteKeyModel.obj({ group_id: group_id, key: nanoid(), issuer_user_id: issuer_user_id, @@ -27,7 +27,7 @@ export default async function ( max_usage: maxUsage, }) - await obj.saveAsync() + await obj.save() - return obj.toJSON() + return obj.toRaw() } diff --git a/packages/server/classes/Spaces/Groups/methods/delete.js b/packages/server/classes/Spaces/Groups/methods/delete.js index 738d1f5a0..dafa39158 100644 --- a/packages/server/classes/Spaces/Groups/methods/delete.js +++ b/packages/server/classes/Spaces/Groups/methods/delete.js @@ -10,18 +10,22 @@ export default async function (group) { const memberships = await GroupMemberships.getByGroupId(group._id) for (const membership of memberships) { - await GroupMemberships.delete(membership._id, group._id, group) - //await membership.deleteAsync() + await GroupMemberships.delete( + membership.user_id, + membership._id, + group._id, + group, + ) } // delete the channels const channels = await GroupChannels.getAllByGroupId(group) for (const channel of channels) { - await channel.deleteAsync() + await channel.delete() } - await this.model.deleteAsync({ _id: group._id }) + await this.model.delete({ _id: group._id }) return group } diff --git a/packages/server/classes/Spaces/Groups/methods/get.js b/packages/server/classes/Spaces/Groups/methods/get.js index b604adcf5..901125510 100644 --- a/packages/server/classes/Spaces/Groups/methods/get.js +++ b/packages/server/classes/Spaces/Groups/methods/get.js @@ -3,7 +3,7 @@ export default async function (group_id, { raw = true } = {}) { throw new OperationError(400, "group_id must be a string") } - const group = await this.model.findOneAsync( + const group = await this.model.findOne( { _id: group_id, }, diff --git a/packages/server/classes/Spaces/Groups/methods/getMany.js b/packages/server/classes/Spaces/Groups/methods/getMany.js index 6d3e5a8cc..194077a17 100644 --- a/packages/server/classes/Spaces/Groups/methods/getMany.js +++ b/packages/server/classes/Spaces/Groups/methods/getMany.js @@ -3,7 +3,7 @@ export default async function (group_ids) { throw new OperationError(400, "group_ids must be an array") } - let groups = await this.model.findAsync( + let groups = await this.model.find( { _id: { $in: group_ids, diff --git a/packages/server/classes/Spaces/Groups/methods/sort.js b/packages/server/classes/Spaces/Groups/methods/sort.js index bc11172a4..7b1364c87 100644 --- a/packages/server/classes/Spaces/Groups/methods/sort.js +++ b/packages/server/classes/Spaces/Groups/methods/sort.js @@ -10,7 +10,7 @@ export default async function (user_id, sortArr) { ) } - await this.sortModel.updateAsync( + await this.sortModel.update( { user_id: user_id, }, diff --git a/packages/server/classes/Spaces/Groups/methods/update.js b/packages/server/classes/Spaces/Groups/methods/update.js index 6e7074e8c..9c70bfba1 100644 --- a/packages/server/classes/Spaces/Groups/methods/update.js +++ b/packages/server/classes/Spaces/Groups/methods/update.js @@ -23,7 +23,19 @@ export default async function (group, payload) { group.reachability = payload.reachability } - await group.saveAsync() + await group.save() + + if (global.websockets) { + try { + global.websockets.senders.toTopic( + `group:${group._id}`, + `group:${group._id}:update`, + group.toRaw(), + ) + } catch (error) { + console.error("Failed to send to group topic", error) + } + } return group } diff --git a/packages/server/classes/Upload/index.ts b/packages/server/classes/Upload/index.ts index 15db5e085..c2a0c9d1d 100644 --- a/packages/server/classes/Upload/index.ts +++ b/packages/server/classes/Upload/index.ts @@ -1,6 +1,8 @@ +// @ts-ignore import fs from "node:fs" +// @ts-ignore import path from "node:path" -import { fileTypeFromBuffer } from "file-type" +import { fileTypeFromBuffer, fileTypeFromFile } from "file-type" import readChunk from "@shared-utils/readChunk" import getFileHash from "@shared-utils/readFileHash" @@ -9,11 +11,12 @@ import putObject from "./putObject" import Transformation from "../Transformation" export type FileHandlePayload = { - user_id: string filePath: string + fileHash?: string + + user_id: string workPath: string - targetPath?: string // mostly provided by processed results - //uploadId?: string + targetPath?: string originalFilename?: string transformations?: Array useCompression?: boolean @@ -26,6 +29,8 @@ export type FileHandlePayload = { export type S3UploadPayload = { filePath: string + fileHash?: string + basePath: string targetPath?: string s3Provider?: string @@ -33,13 +38,30 @@ export type S3UploadPayload = { originalFilename?: string } +export type FileIntegrityResult = { + isValid: boolean + fileSize: number + fileHash: string + error?: string +} + export default class Upload { static fileHandle = async (payload: FileHandlePayload) => { + const integrityCheck = await Upload.validateFileIntegrity( + payload.filePath, + ) + + if (!integrityCheck.isValid) { + throw new OperationError( + 400, + `File integrity check failed: ${integrityCheck.error}`, + ) + } + if (!payload.transformations) { payload.transformations = [] } - // if compression is enabled and no transformations are provided, add basic transformations for images or videos if ( payload.useCompression === true && payload.transformations.length === 0 @@ -47,18 +69,15 @@ export default class Upload { payload.transformations.push("optimize") } - // process file upload if transformations are provided if (payload.transformations.length > 0) { - // process const processed = await Upload.transform(payload) - - // overwrite filePath payload.filePath = processed.filePath } - // upload const result = await Upload.toS3({ filePath: payload.filePath, + fileHash: payload.fileHash, + targetPath: payload.targetPath, basePath: payload.user_id, onProgress: payload.onProgress, @@ -66,7 +85,6 @@ export default class Upload { originalFilename: payload.originalFilename, }) - // delete workpath await fs.promises.rm(payload.workPath, { recursive: true, force: true }) return result @@ -83,16 +101,13 @@ export default class Upload { capabilities: payload.capabilities, }) - // if is a file, overwrite filePath if (transformationResult.outputFile) { payload.filePath = transformationResult.outputFile } - // if is a directory, overwrite filePath to upload entire directory if (transformationResult.outputPath) { payload.filePath = transformationResult.outputPath payload.targetPath = transformationResult.outputFile - //payload.isDirectory = true } } } @@ -103,6 +118,8 @@ export default class Upload { static toS3 = async (payload: S3UploadPayload) => { const { filePath, + fileHash, + basePath, targetPath, s3Provider, @@ -110,11 +127,11 @@ export default class Upload { originalFilename, } = payload - // if targetPath is provided, means its a directory const isDirectory = !!targetPath const metadata = await this.buildFileMetadata( isDirectory ? targetPath : filePath, + fileHash, ) let uploadPath = path.join(basePath, metadata["File-Hash"]) @@ -136,15 +153,6 @@ export default class Upload { metadata["x-amz-acl"] = "public-read" - // console.log("Uploading to S3:", { - // filePath: filePath, - // basePath: basePath, - // uploadPath: uploadPath, - // targetPath: targetPath, - // metadata: metadata, - // s3Provider: s3Provider, - // }) - const result = await putObject({ filePath: filePath, uploadPath: uploadPath, @@ -160,16 +168,85 @@ export default class Upload { static async buildFileMetadata( filePath: string, + fileHash?: string, ): Promise<{ [key: string]: string }> { - const firstBuffer = await readChunk(filePath, { - length: 4100, - }) - const fileHash = await getFileHash(fs.createReadStream(filePath)) - const fileType = await fileTypeFromBuffer(firstBuffer) + // const firstBuffer = await readChunk(filePath, { + // length: 4100, + // }) + + const fileType = await fileTypeFromFile(filePath) + + // if no hash provided, use the fallback computation + if (!fileHash) { + fileHash = await getFileHash(fs.createReadStream(filePath)) + } return { - "File-Hash": fileHash, "Content-Type": fileType?.mime ?? "application/octet-stream", + "File-Hash": fileHash, + } + } + + static async validateFileIntegrity( + filePath: string, + ): Promise { + try { + const stats = await fs.promises.stat(filePath) + + if (!stats.isFile()) { + return { + isValid: false, + fileSize: 0, + fileHash: "", + error: "Path is not a file", + } + } + + if (stats.size === 0) { + return { + isValid: false, + fileSize: 0, + fileHash: "", + error: "File is empty", + } + } + + const fileHash = await getFileHash(fs.createReadStream(filePath)) + + if (!fileHash || fileHash.length === 0) { + return { + isValid: false, + fileSize: stats.size, + fileHash: "", + error: "Failed to calculate file hash", + } + } + + const firstBuffer = await readChunk(filePath, { + length: 512, + }) + + if (!firstBuffer || firstBuffer.length === 0) { + return { + isValid: false, + fileSize: stats.size, + fileHash: fileHash, + error: "Failed to read file content", + } + } + + return { + isValid: true, + fileSize: stats.size, + fileHash: fileHash, + } + } catch (error) { + return { + isValid: false, + fileSize: 0, + fileHash: "", + error: `Integrity check error: ${error instanceof Error ? error.message : String(error)}`, + } } } } diff --git a/packages/server/db/auth_session.ts b/packages/server/db/auth_session.ts new file mode 100644 index 000000000..e693d32a0 --- /dev/null +++ b/packages/server/db/auth_session.ts @@ -0,0 +1,41 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "auth_sessions", + keys: [["_id"], "user_id"], + }, + { + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + token: { + type: ColumnTypes.Varchar, + } as Column, + user_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + username: { + type: ColumnTypes.Varchar, + } as Column, + sign_location: { + type: ColumnTypes.Varchar, + } as Column, + ip_address: { + type: ColumnTypes.Varchar, + } as Column, + client: { + type: ColumnTypes.Varchar, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("auth_sessions", schema) + +export default model diff --git a/packages/server/db/channel_deleted_messages.ts b/packages/server/db/channel_deleted_messages.ts new file mode 100644 index 000000000..054f5c70d --- /dev/null +++ b/packages/server/db/channel_deleted_messages.ts @@ -0,0 +1,32 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "channel_deleted_messages", + keys: [["channel_id"], "_id"], + clustering_order: { _id: "asc" }, + }, + { + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + channel_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + deleted_by_user_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + deleted_at: { + type: ColumnTypes.Timestamp, + required: true, + } as Column, + }, +) + +export const model = new Model("channel_deleted_messages", schema) + +export default model diff --git a/packages/server/db/channel_log.ts b/packages/server/db/channel_log.ts new file mode 100644 index 000000000..1a5d23da3 --- /dev/null +++ b/packages/server/db/channel_log.ts @@ -0,0 +1,36 @@ +import { ColumnTypes, Model, Schema } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "channel_log", + keys: [["channel_id"], "log_id"], + clustering_order: { + channel_id: "desc", + }, + }, + { + channel_id: { + type: ColumnTypes.Varchar, + } as Column, + log_id: { + type: ColumnTypes.Varchar, + } as Column, + type: { + type: ColumnTypes.Varchar, + } as Column, + target_id: { + type: ColumnTypes.Varchar, + } as Column, + actor_id: { + type: ColumnTypes.Varchar, + } as Column, + timestamp: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("channel_log", schema) + +export default model diff --git a/packages/server/db/channel_messages.ts b/packages/server/db/channel_messages.ts new file mode 100644 index 000000000..d719ecb89 --- /dev/null +++ b/packages/server/db/channel_messages.ts @@ -0,0 +1,48 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "channel_messages", + keys: [["channel_id"], "_id"], + clustering_order: { _id: "asc" }, + }, + { + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + channel_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + user_id: { + type: ColumnTypes.Varchar, + } as Column, + message: { + type: ColumnTypes.Varchar, + } as Column, + attachments: { + type: "frozen>>", + } as Column>, + flags: { + type: "frozen>", + } as Column, + sticker: { + type: ColumnTypes.Varchar, + } as Column, + reply_to_id: { + type: ColumnTypes.Varchar, + } as Column, + updated_at: { + type: ColumnTypes.Timestamp, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("channel_messages", schema) + +export default model diff --git a/packages/server/db/channel_orders.ts b/packages/server/db/channel_orders.ts new file mode 100644 index 000000000..caf1e6a62 --- /dev/null +++ b/packages/server/db/channel_orders.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_channels_order", + keys: ["group_id"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + order: { + type: "list", + } as Column, + }, +) + +export const model = new Model("channel_orders", schema) + +export default model diff --git a/packages/server/db/direct_messages_activity.ts b/packages/server/db/direct_messages_activity.ts new file mode 100644 index 000000000..c45df400b --- /dev/null +++ b/packages/server/db/direct_messages_activity.ts @@ -0,0 +1,35 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "direct_messages_activity", + keys: [["user_id"], "room_id"], + }, + { + user_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + room_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + to_user_id: { + type: ColumnTypes.Varchar, + } as Column, + last_message_at: { + type: ColumnTypes.Timestamp, + } as Column, + direction: { + type: ColumnTypes.Text, + } as Column, + short_message: { + type: ColumnTypes.Text, + } as Column, + }, +) + +export const model = new Model("direct_messages_activity", schema) + +export default model diff --git a/packages/server/db/direct_messages_rooms.ts b/packages/server/db/direct_messages_rooms.ts new file mode 100644 index 000000000..3ffd894ba --- /dev/null +++ b/packages/server/db/direct_messages_rooms.ts @@ -0,0 +1,29 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "direct_messages_rooms", + keys: [["pair_key"], "_id"], + }, + { + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + pair_key: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + name: { + type: ColumnTypes.Varchar, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("direct_messages_rooms", schema) + +export default model diff --git a/packages/server/db/group_channels.ts b/packages/server/db/group_channels.ts new file mode 100644 index 000000000..cf2402cd3 --- /dev/null +++ b/packages/server/db/group_channels.ts @@ -0,0 +1,44 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_channels", + keys: [["group_id"], "_id"], + }, + { + __v: { + type: ColumnTypes.Bigint, + } as Column, + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + kind: { + type: ColumnTypes.Varchar, + } as Column, + name: { + type: ColumnTypes.Varchar, + } as Column, + description: { + type: ColumnTypes.Varchar, + } as Column, + explicit: { + type: ColumnTypes.Boolean, + } as Column, + params: { + type: "map", + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("group_channels", schema) + +export default model diff --git a/packages/server/db/group_channels_last_message_id.ts b/packages/server/db/group_channels_last_message_id.ts new file mode 100644 index 000000000..2ad1d1222 --- /dev/null +++ b/packages/server/db/group_channels_last_message_id.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_channels_last_message_id", + keys: ["channel_id"], + }, + { + channel_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + _id: { + type: ColumnTypes.Varchar, + } as Column, + }, +) + +export const model = new Model("group_channels_last_message_id", schema) + +export default model diff --git a/packages/server/db/group_invite_key.ts b/packages/server/db/group_invite_key.ts new file mode 100644 index 000000000..50ac4bcc7 --- /dev/null +++ b/packages/server/db/group_invite_key.ts @@ -0,0 +1,38 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "groups_invite_keys", + keys: [["group_id"], "key"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + key: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + issuer_user_id: { + type: ColumnTypes.Varchar, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + expires_at: { + type: ColumnTypes.Timestamp, + } as Column, + max_usage: { + type: ColumnTypes.Int, + } as Column, + usages: { + type: ColumnTypes.Int, + } as Column, + }, +) + +export const model = new Model("group_invite_key", schema) + +export default model diff --git a/packages/server/db/group_memberships.ts b/packages/server/db/group_memberships.ts new file mode 100644 index 000000000..9ade8ab82 --- /dev/null +++ b/packages/server/db/group_memberships.ts @@ -0,0 +1,33 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_memberships", + keys: [["user_id"], "group_id", "_id"], + }, + { + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + user_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + roles: { + type: "frozen>", + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("group_memberships", schema) + +export default model diff --git a/packages/server/db/group_memberships_counter.ts b/packages/server/db/group_memberships_counter.ts new file mode 100644 index 000000000..07c2fa027 --- /dev/null +++ b/packages/server/db/group_memberships_counter.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_memberships_counter", + keys: ["group_id"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + counter: { + type: ColumnTypes.Counter, + } as Column, + }, +) + +export const model = new Model("group_memberships_counter", schema) + +export default model diff --git a/packages/server/db/group_memberships_ref.ts b/packages/server/db/group_memberships_ref.ts new file mode 100644 index 000000000..413b8e437 --- /dev/null +++ b/packages/server/db/group_memberships_ref.ts @@ -0,0 +1,29 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_memberships_ref", + keys: [["group_id"], "created_at"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + user_id: { + type: ColumnTypes.Varchar, + } as Column, + membership_id: { + type: ColumnTypes.Varchar, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + required: true, + } as Column, + }, +) + +export const model = new Model("group_memberships_ref", schema) + +export default model diff --git a/packages/server/db/group_roles.ts b/packages/server/db/group_roles.ts new file mode 100644 index 000000000..dfe73f711 --- /dev/null +++ b/packages/server/db/group_roles.ts @@ -0,0 +1,26 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_roles", + keys: [["group_id"], "role_key"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + role_key: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + permissions: { + type: "frozen>>", + } as Column, + }, +) + +export const model = new Model("group_roles", schema) + +export default model diff --git a/packages/server/db/group_versions.ts b/packages/server/db/group_versions.ts new file mode 100644 index 000000000..b0be77edd --- /dev/null +++ b/packages/server/db/group_versions.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "group_versions", + keys: ["group_id"], + }, + { + group_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + __v: { + type: ColumnTypes.Counter, + } as Column, + }, +) + +export const model = new Model("group_versions", schema) + +export default model diff --git a/packages/server/db/groups.ts b/packages/server/db/groups.ts new file mode 100644 index 000000000..6b2a2f506 --- /dev/null +++ b/packages/server/db/groups.ts @@ -0,0 +1,43 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "groups", + keys: ["_id"], + }, + { + __v: { + type: ColumnTypes.Int, + } as Column, + _id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + name: { + type: ColumnTypes.Varchar, + } as Column, + description: { + type: ColumnTypes.Varchar, + } as Column, + icon: { + type: ColumnTypes.Varchar, + } as Column, + cover: { + type: ColumnTypes.Varchar, + } as Column, + reachability: { + type: ColumnTypes.Varchar, + } as Column, + owner_user_id: { + type: ColumnTypes.Varchar, + } as Column, + created_at: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("groups", schema) + +export default model diff --git a/packages/server/db/groups_user_orders.ts b/packages/server/db/groups_user_orders.ts new file mode 100644 index 000000000..a6d1c4541 --- /dev/null +++ b/packages/server/db/groups_user_orders.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "groups_user_orders", + keys: ["user_id"], + }, + { + user_id: { + type: ColumnTypes.Varchar, + required: true, + } as Column, + order: { + type: "list", + } as Column, + }, +) + +export const model = new Model("groups_user_orders", schema) + +export default model diff --git a/packages/server/db/oidc_apps.ts b/packages/server/db/oidc_apps.ts new file mode 100644 index 000000000..efa4959cc --- /dev/null +++ b/packages/server/db/oidc_apps.ts @@ -0,0 +1,37 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "oidc_apps", + keys: ["client_id"], + }, + { + client_id: { + type: ColumnTypes.Text, + required: true, + } as Column, + client_secret: { + type: ColumnTypes.Text, + } as Column, + owner_id: { + type: ColumnTypes.Uuid, + } as Column, + client_name: { + type: ColumnTypes.Text, + } as Column, + redirect_uris: { + type: "list", + } as Column, + grant_types: { + type: "list", + } as Column, + response_types: { + type: "list", + } as Column, + }, +) + +export const model = new Model("oidc_apps", schema) + +export default model diff --git a/packages/server/db/oidc_store.ts b/packages/server/db/oidc_store.ts new file mode 100644 index 000000000..9b9595b36 --- /dev/null +++ b/packages/server/db/oidc_store.ts @@ -0,0 +1,34 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "oidc_store", + keys: ["id"], + }, + { + id: { + type: ColumnTypes.Text, + required: true, + } as Column, + type: { + type: ColumnTypes.Text, + } as Column, + payload: { + type: ColumnTypes.Text, + } as Column, + grantId: { + type: ColumnTypes.Text, + } as Column, + uid: { + type: ColumnTypes.Text, + } as Column, + consumedAt: { + type: ColumnTypes.Timestamp, + } as Column, + }, +) + +export const model = new Model("oidc_store", schema) + +export default model diff --git a/packages/server/db/test_key.ts b/packages/server/db/test_key.ts new file mode 100644 index 000000000..e6de3bf45 --- /dev/null +++ b/packages/server/db/test_key.ts @@ -0,0 +1,22 @@ +import { Model, Schema, ColumnTypes } from "@ragestudio/scylla-odm" +import type { Column } from "@ragestudio/scylla-odm/types" + +export const schema = new Schema( + { + table_name: "test_data_table", + keys: ["key"], + }, + { + key: { + type: ColumnTypes.Text, + required: true, + } as Column, + value: { + type: ColumnTypes.Text, + } as Column, + }, +) + +export const model = new Model("test", schema) + +export default model diff --git a/packages/server/middlewares/withAuthentication/index.js b/packages/server/middlewares/withAuthentication/index.js index 1ab0772e3..098fb2758 100755 --- a/packages/server/middlewares/withAuthentication/index.js +++ b/packages/server/middlewares/withAuthentication/index.js @@ -1,6 +1,6 @@ import AuthToken from "../../classes/AuthToken" import ServerToken from "../../classes/ServerToken" -import BotToken from "../../classes/BotToken" +//import BotToken from "../../classes/BotToken" export default async (req, res) => { function reject(data) { diff --git a/packages/server/package-lock.json b/packages/server/package-lock.json index 0786cc0b4..0d9a07008 100644 --- a/packages/server/package-lock.json +++ b/packages/server/package-lock.json @@ -1,895 +1,1234 @@ { "name": "@comty/server", - "version": "2.10.0@alpha", + "version": "2.14.0@alpha", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@comty/server", - "version": "2.10.0@alpha", + "version": "2.14.0@alpha", "hasInstallScript": true, "license": "ComtyLicense", "workspaces": [ "services/*" ], "dependencies": { + "@foxify/events": "^2.1.0", + "@ragestudio/scylla-odm": "^0.21.0", "@sentry/node": "^10.44.0", - "axios": "^1.13.6", + "@types/luxon": "^3.7.1", + "axios": "^1.16.0", "bcrypt": "^6.0.0", "bullmq": "^5.71.0", - "cassandra-driver": "^4.8.0", "cross-env": "^10.1.0", - "express-cassandra": "^2.9.1", "jsonwebtoken": "^9.0.3", "jws": "^4.0.1", "linebridge": "^1.8.1", + "lodash": "^4.18.1", "minio": "^8.0.7", "mongoose": "^9.3.1", "qs": "^6.15.0" }, "devDependencies": { "@eslint/js": "^10.0.1", + "@types/jest": "^29.5.0", "@typescript-eslint/eslint-plugin": "^8.57.1", + "@vitest/coverage-v8": "^3.0.9", "chai": "^6.2.2", "eslint": "^10.0.3", "globals": "^17.4.0", + "jest": "^29.5.0", "mocha": "^12.0.0-beta.9", - "sinon": "^21.0.3" + "sinon": "^21.0.3", + "ts-jest": "^29.1.0", + "vitest": "^3.0.9" }, "optionalDependencies": { "bufferutil": "^4.1.0" } }, - "node_modules/@borewit/text-codec": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", - "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "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/@epic-web/invariant": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", - "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", - "license": "MIT" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.4.3" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "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": ">=6.9.0" } }, - "node_modules/@eslint-community/eslint-utils/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/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "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/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=6.9.0" } }, - "node_modules/@eslint/config-array": { - "version": "0.23.3", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", - "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/object-schema": "^3.0.3", - "debug": "^4.3.1", - "minimatch": "^10.2.4" + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=6.9.0" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", - "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "@eslint/core": "^1.1.0" - }, + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/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/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=6.9.0" } }, - "node_modules/@eslint/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", - "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=6.9.0" } }, - "node_modules/@eslint/js": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", - "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, - "funding": { - "url": "https://eslint.org/donate" + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "eslint": "^10.0.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "@babel/core": "^7.0.0" } }, - "node_modules/@eslint/object-schema": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", - "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=6.9.0" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", - "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.1", - "levn": "^0.4.1" - }, + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=6.9.0" } }, - "node_modules/@fastify/merge-json-schemas": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", - "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, "license": "MIT", - "dependencies": { - "dequal": "^2.0.3" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@fastify/otel": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.17.1.tgz", - "integrity": "sha512-K4wyxfUZx2ux5o+b6BtTqouYFVILohLZmSbA2tKUueJstNcBnoGPVhllCaOvbQ3ZrXdUxUC/fyrSWSCqHhdOPg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, "license": "MIT", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.212.0", - "@opentelemetry/semantic-conventions": "^1.28.0", - "minimatch": "^10.2.4" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@fastify/otel/node_modules/@opentelemetry/api-logs": { - "version": "0.212.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", - "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", - "license": "Apache-2.0", + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/api": "^1.3.0" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=6.9.0" } }, - "node_modules/@fastify/otel/node_modules/@opentelemetry/instrumentation": { - "version": "0.212.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", - "integrity": "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==", - "license": "Apache-2.0", + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/api-logs": "0.212.0", - "import-in-the-middle": "^2.0.6", - "require-in-the-middle": "^8.0.0" + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=6.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": { - "@opentelemetry/api": "^1.3.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@fastify/otel/node_modules/import-in-the-middle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", - "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", - "license": "Apache-2.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": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@foxify/events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@foxify/events/-/events-2.1.0.tgz", - "integrity": "sha512-aMLFeeQgzAH/ft9VNGwQasr2lAXLIxk1VAYIUDM9G8HQX0yow6b7z/wm42e4s6JHU8zGu940sLj5FeglkFnEFQ==", + "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", - "workspaces": [ - "benchmarks" - ] + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "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": "Apache-2.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=18.18.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { - "node": ">=18.18.0" - } + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "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/@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": "Apache-2.0", + "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.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, "engines": { - "node": ">=12.22" + "node": ">=6.9.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "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": "Apache-2.0", + "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": ">=18.18" + "node": ">=6.9.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@infisical/sdk": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk/-/sdk-2.3.5.tgz", - "integrity": "sha512-vaQmDyzOFRkiZqstifk2dHTctkfizhlv7/+Ds6PFVWPGUpRUqP4PoR4yRdx2405IKWVx/ABuqQ4S8e9ix1kwzg==", - "license": "SEE LICENSE IN LICENSE", + "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": ">= 10" + "node": ">=6.9.0" }, - "optionalDependencies": { - "@infisical/sdk-android-arm-eabi": "2.3.5", - "@infisical/sdk-android-arm64": "2.3.5", - "@infisical/sdk-darwin-arm64": "2.3.5", - "@infisical/sdk-darwin-x64": "2.3.5", - "@infisical/sdk-linux-arm-gnueabihf": "2.3.5", - "@infisical/sdk-linux-arm64-gnu": "2.3.5", - "@infisical/sdk-linux-arm64-musl": "2.3.5", - "@infisical/sdk-linux-x64-gnu": "2.3.5", - "@infisical/sdk-linux-x64-musl": "2.3.5", - "@infisical/sdk-win32-arm64-msvc": "2.3.5", - "@infisical/sdk-win32-ia32-msvc": "2.3.5", - "@infisical/sdk-win32-x64-msvc": "2.3.5" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@infisical/sdk-android-arm-eabi": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-android-arm-eabi/-/sdk-android-arm-eabi-2.3.5.tgz", - "integrity": "sha512-7KGWJ5X/RV6sIHWt3mjNg+zykzYvbHIKmNKBHTTAOuULKpTIAoQyFD1q3XMylP2AaVh8BJtgVOODO4/Uxexlug==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.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/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@epic-web/invariant": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", + "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", "cpu": [ - "arm" + "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "android" + "aix" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-android-arm64": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-android-arm64/-/sdk-android-arm64-2.3.5.tgz", - "integrity": "sha512-jHCvwYYchtTWryAGX2MvddRVZFdGrdoakGTMrvPQ0ZyM1XnLo3Q9tb35RCjTTylE1q114OKGRymM2JZ10ygiRw==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", "cpu": [ - "arm64" + "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-darwin-arm64": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-darwin-arm64/-/sdk-darwin-arm64-2.3.5.tgz", - "integrity": "sha512-UEe38OTxjlOMo2HVplmT6pmXwks0c9lckKDUKK/MNfp0H9n4RJKXd8jco1BeG713eNR7bX01Q2c74XgLJhf58Q==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "android" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-darwin-x64": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-darwin-x64/-/sdk-darwin-x64-2.3.5.tgz", - "integrity": "sha512-mMz/1N+aZjvIXPHMnfl9DmyYWCXjRsa/Uxj94pXjJGZ3GMsANRTR08GVRI2S2XWMODiV5D9zY2mQ3/eY5E5Y/A==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "android" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-linux-arm-gnueabihf": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm-gnueabihf/-/sdk-linux-arm-gnueabihf-2.3.5.tgz", - "integrity": "sha512-GjVQNdv8aYn+mZgW/sRFirwb0iMRX7ShBC0N8MsgrSBxnSpH2nFiUFj8hFi2DOvR5NbJ+KQpabfvP0eodozKSg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", "cpu": [ - "arm" + "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-linux-arm64-gnu": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm64-gnu/-/sdk-linux-arm64-gnu-2.3.5.tgz", - "integrity": "sha512-hclvvD1eAYB6JP58mo5TfBjE+vSGSv30fNuXeaheO4yOLfnaGyCCR6E6F96uxNNCAVkVO4RXRhiSSCT6K3f3jA==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", "cpu": [ - "arm64" + "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-linux-arm64-musl": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm64-musl/-/sdk-linux-arm64-musl-2.3.5.tgz", - "integrity": "sha512-RFYd49eXoUtXXUsQb9Cqiu0RKp32GrsEATj9GlMJYharDn8BZhYr6lpDb+7EZolbjg+A40JvT98nqN2EliUwgA==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-linux-x64-gnu": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-x64-gnu/-/sdk-linux-x64-gnu-2.3.5.tgz", - "integrity": "sha512-E0JB4fowk9cmfQGBJw8QNXy9TBewB42kyQhCYARQtPvleXqoK48DUs7mzRIawLUbyCA5ldcy2jFbj/ZXWWYNOA==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-linux-x64-musl": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-x64-musl/-/sdk-linux-x64-musl-2.3.5.tgz", - "integrity": "sha512-3+irZY69oepYAwXXgTUDIW6PbjLRmj79rzA4CSKfF3a0wBLlR+6e+1NT+nu87BtP3wSBej3y1JAnfw853AekDA==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", "cpu": [ - "x64" + "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-win32-arm64-msvc": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-arm64-msvc/-/sdk-win32-arm64-msvc-2.3.5.tgz", - "integrity": "sha512-DVZMglFSE3Xqj7/Bsv/4KfhfAO970BsSdOL3LrlRvcN3Dkocuthh3rHw6U5jg92FfMw+hMN9DzlhTqtUBZWYjQ==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-win32-ia32-msvc": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-ia32-msvc/-/sdk-win32-ia32-msvc-2.3.5.tgz", - "integrity": "sha512-dw3XuR2myJ2leB3+KStFsHB2zIJ29TArvoU/zGw/cdCOj1dRKF7WcahWg1id+ydwoeOv+HVZ+RsS8sZR5gYblQ==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@infisical/sdk-win32-x64-msvc": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-x64-msvc/-/sdk-win32-x64-msvc-2.3.5.tgz", - "integrity": "sha512-SWzYndKhHih4zE/OYWfv9QoYaj5oDBhNSKZAlw1XFYdlUU41nTCN1nruD9RRdmjoJ/pF0sn2Mr9v+OiXStnC+A==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", "cpu": [ - "x64" + "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/@ioredis/commands": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", - "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", - "license": "MIT" - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.0.0" + "node": ">=18" } }, - "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==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "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==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "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==", - "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==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@koa/cors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", - "integrity": "sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==", + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "vary": "^1.1.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 14.0.0" + "node": ">=18" } }, - "node_modules/@koa/router": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@koa/router/-/router-15.3.0.tgz", - "integrity": "sha512-s87hWJjFYky2Z97u8jzah73sSHp4IZivD/2PZCuspHRvcKU69OPLoBIbKigVlBmS50yFTh9GHFfr1hDag4+wXw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "http-errors": "^2.0.1", - "koa-compose": "^4.1.0", - "path-to-regexp": "^8.3.0" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "koa": "^2.0.0 || ^3.0.0" - }, - "peerDependenciesMeta": { - "koa": { - "optional": false - } + "node": ">=18" } }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", - "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "sparse-bitfield": "^3.0.3" + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", "cpu": [ - "arm" + "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openharmony" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", "cpu": [ - "arm64" + "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "sunos" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", "cpu": [ - "x64" + "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "win32" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", "cpu": [ - "x64" + "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 18" + "node": ">=18" } }, - "node_modules/@octokit/core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", - "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.1.0", - "@octokit/request": "^8.4.1", - "@octokit/request-error": "^5.1.1", - "@octokit/types": "^13.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/endpoint": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", - "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" + "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/eslint-utils/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==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@octokit/graphql": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", - "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "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==", + "dev": true, "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.3", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.3.tgz", + "integrity": "sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@octokit/request": "^8.4.1", - "@octokit/types": "^13.0.0", - "universal-user-agent": "^6.0.0" + "@eslint/object-schema": "^3.0.3", + "debug": "^4.3.1", + "minimatch": "^10.2.4" }, "engines": { - "node": ">= 18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@octokit/openapi-types": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", - "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "11.4.4-cjs.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", - "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", - "license": "MIT", + "node_modules/@eslint/config-helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", + "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@octokit/types": "^13.7.0" + "@eslint/core": "^1.1.0" }, "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": "5" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", - "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", - "license": "MIT", - "engines": { - "node": ">= 18" + "node_modules/@eslint/core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.1.tgz", + "integrity": "sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" }, - "peerDependencies": { - "@octokit/core": "5" + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "13.3.2-cjs.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", - "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, "license": "MIT", - "dependencies": { - "@octokit/types": "^13.8.0" - }, "engines": { - "node": ">= 18" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" }, "peerDependencies": { - "@octokit/core": "^5" + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/@octokit/request": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", - "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^9.0.6", - "@octokit/request-error": "^5.1.1", - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" - }, + "node_modules/@eslint/object-schema": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.3.tgz", + "integrity": "sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@octokit/request-error": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", - "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", - "license": "MIT", + "node_modules/@eslint/plugin-kit": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz", + "integrity": "sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@octokit/types": "^13.1.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" + "@eslint/core": "^1.1.1", + "levn": "^0.4.1" }, "engines": { - "node": ">= 18" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@octokit/rest": { - "version": "20.1.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", - "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", + "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT", "dependencies": { - "@octokit/core": "^5.0.2", - "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", - "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" - }, - "engines": { - "node": ">= 18" + "dequal": "^2.0.3" } }, - "node_modules/@octokit/types": { - "version": "13.10.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", - "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "node_modules/@fastify/otel": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.17.1.tgz", + "integrity": "sha512-K4wyxfUZx2ux5o+b6BtTqouYFVILohLZmSbA2tKUueJstNcBnoGPVhllCaOvbQ3ZrXdUxUC/fyrSWSCqHhdOPg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^24.2.0" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=8.0.0" + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.212.0", + "@opentelemetry/semantic-conventions": "^1.28.0", + "minimatch": "^10.2.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" } }, - "node_modules/@opentelemetry/api-logs": { - "version": "0.213.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.213.0.tgz", - "integrity": "sha512-zRM5/Qj6G84Ej3F1yt33xBVY/3tnMxtL1fiDIxYbDWYaZ/eudVw3/PBiZ8G7JwUxXxjW8gU4g6LnOyfGKYHYgw==", + "node_modules/@fastify/otel/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -898,2766 +1237,6074 @@ "node": ">=8.0.0" } }, - "node_modules/@opentelemetry/context-async-hooks": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.6.0.tgz", - "integrity": "sha512-L8UyDwqpTcbkIK5cgwDRDYDoEhQoj8wp8BwsO19w3LB1Z41yEQm2VJyNfAi9DrLP/YTqXqWpKHyZfR9/tFYo1Q==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/core": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.0.tgz", - "integrity": "sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==", + "node_modules/@fastify/otel/node_modules/@opentelemetry/instrumentation": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", + "integrity": "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==", "license": "Apache-2.0", - "peer": true, "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" + "@opentelemetry/api-logs": "0.212.0", + "import-in-the-middle": "^2.0.6", + "require-in-the-middle": "^8.0.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@opentelemetry/instrumentation": { - "version": "0.213.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.213.0.tgz", - "integrity": "sha512-3i9NdkET/KvQomeh7UaR/F4r9P25Rx6ooALlWXPIjypcEOUxksCmVu0zA70NBJWlrMW1rPr/LRidFAflLI+s/w==", + "node_modules/@fastify/otel/node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, + "node_modules/@foxify/events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@foxify/events/-/events-2.1.0.tgz", + "integrity": "sha512-aMLFeeQgzAH/ft9VNGwQasr2lAXLIxk1VAYIUDM9G8HQX0yow6b7z/wm42e4s6JHU8zGu940sLj5FeglkFnEFQ==", + "license": "MIT", + "workspaces": [ + "benchmarks" + ] + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@infisical/sdk": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk/-/sdk-2.3.5.tgz", + "integrity": "sha512-vaQmDyzOFRkiZqstifk2dHTctkfizhlv7/+Ds6PFVWPGUpRUqP4PoR4yRdx2405IKWVx/ABuqQ4S8e9ix1kwzg==", + "license": "SEE LICENSE IN LICENSE", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@infisical/sdk-android-arm-eabi": "2.3.5", + "@infisical/sdk-android-arm64": "2.3.5", + "@infisical/sdk-darwin-arm64": "2.3.5", + "@infisical/sdk-darwin-x64": "2.3.5", + "@infisical/sdk-linux-arm-gnueabihf": "2.3.5", + "@infisical/sdk-linux-arm64-gnu": "2.3.5", + "@infisical/sdk-linux-arm64-musl": "2.3.5", + "@infisical/sdk-linux-x64-gnu": "2.3.5", + "@infisical/sdk-linux-x64-musl": "2.3.5", + "@infisical/sdk-win32-arm64-msvc": "2.3.5", + "@infisical/sdk-win32-ia32-msvc": "2.3.5", + "@infisical/sdk-win32-x64-msvc": "2.3.5" + } + }, + "node_modules/@infisical/sdk-android-arm-eabi": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-android-arm-eabi/-/sdk-android-arm-eabi-2.3.5.tgz", + "integrity": "sha512-7KGWJ5X/RV6sIHWt3mjNg+zykzYvbHIKmNKBHTTAOuULKpTIAoQyFD1q3XMylP2AaVh8BJtgVOODO4/Uxexlug==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-android-arm64": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-android-arm64/-/sdk-android-arm64-2.3.5.tgz", + "integrity": "sha512-jHCvwYYchtTWryAGX2MvddRVZFdGrdoakGTMrvPQ0ZyM1XnLo3Q9tb35RCjTTylE1q114OKGRymM2JZ10ygiRw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-darwin-arm64": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-darwin-arm64/-/sdk-darwin-arm64-2.3.5.tgz", + "integrity": "sha512-UEe38OTxjlOMo2HVplmT6pmXwks0c9lckKDUKK/MNfp0H9n4RJKXd8jco1BeG713eNR7bX01Q2c74XgLJhf58Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-darwin-x64": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-darwin-x64/-/sdk-darwin-x64-2.3.5.tgz", + "integrity": "sha512-mMz/1N+aZjvIXPHMnfl9DmyYWCXjRsa/Uxj94pXjJGZ3GMsANRTR08GVRI2S2XWMODiV5D9zY2mQ3/eY5E5Y/A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-linux-arm-gnueabihf": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm-gnueabihf/-/sdk-linux-arm-gnueabihf-2.3.5.tgz", + "integrity": "sha512-GjVQNdv8aYn+mZgW/sRFirwb0iMRX7ShBC0N8MsgrSBxnSpH2nFiUFj8hFi2DOvR5NbJ+KQpabfvP0eodozKSg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-linux-arm64-gnu": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm64-gnu/-/sdk-linux-arm64-gnu-2.3.5.tgz", + "integrity": "sha512-hclvvD1eAYB6JP58mo5TfBjE+vSGSv30fNuXeaheO4yOLfnaGyCCR6E6F96uxNNCAVkVO4RXRhiSSCT6K3f3jA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-linux-arm64-musl": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-arm64-musl/-/sdk-linux-arm64-musl-2.3.5.tgz", + "integrity": "sha512-RFYd49eXoUtXXUsQb9Cqiu0RKp32GrsEATj9GlMJYharDn8BZhYr6lpDb+7EZolbjg+A40JvT98nqN2EliUwgA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-linux-x64-gnu": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-x64-gnu/-/sdk-linux-x64-gnu-2.3.5.tgz", + "integrity": "sha512-E0JB4fowk9cmfQGBJw8QNXy9TBewB42kyQhCYARQtPvleXqoK48DUs7mzRIawLUbyCA5ldcy2jFbj/ZXWWYNOA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-linux-x64-musl": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-linux-x64-musl/-/sdk-linux-x64-musl-2.3.5.tgz", + "integrity": "sha512-3+irZY69oepYAwXXgTUDIW6PbjLRmj79rzA4CSKfF3a0wBLlR+6e+1NT+nu87BtP3wSBej3y1JAnfw853AekDA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-win32-arm64-msvc": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-arm64-msvc/-/sdk-win32-arm64-msvc-2.3.5.tgz", + "integrity": "sha512-DVZMglFSE3Xqj7/Bsv/4KfhfAO970BsSdOL3LrlRvcN3Dkocuthh3rHw6U5jg92FfMw+hMN9DzlhTqtUBZWYjQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-win32-ia32-msvc": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-ia32-msvc/-/sdk-win32-ia32-msvc-2.3.5.tgz", + "integrity": "sha512-dw3XuR2myJ2leB3+KStFsHB2zIJ29TArvoU/zGw/cdCOj1dRKF7WcahWg1id+ydwoeOv+HVZ+RsS8sZR5gYblQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@infisical/sdk-win32-x64-msvc": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@infisical/sdk-win32-x64-msvc/-/sdk-win32-x64-msvc-2.3.5.tgz", + "integrity": "sha512-SWzYndKhHih4zE/OYWfv9QoYaj5oDBhNSKZAlw1XFYdlUU41nTCN1nruD9RRdmjoJ/pF0sn2Mr9v+OiXStnC+A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz", + "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==", + "license": "MIT" + }, + "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/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", + "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/@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/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "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" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/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/@jest/reporters/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@jest/reporters/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/@jest/reporters/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/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.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==", + "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==", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@koa/cors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", + "integrity": "sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==", + "license": "MIT", + "dependencies": { + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@koa/router": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-15.3.0.tgz", + "integrity": "sha512-s87hWJjFYky2Z97u8jzah73sSHp4IZivD/2PZCuspHRvcKU69OPLoBIbKigVlBmS50yFTh9GHFfr1hDag4+wXw==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "koa-compose": "^4.1.0", + "path-to-regexp": "^8.3.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "koa": "^2.0.0 || ^3.0.0" + }, + "peerDependenciesMeta": { + "koa": { + "optional": false + } + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.213.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.213.0.tgz", + "integrity": "sha512-zRM5/Qj6G84Ej3F1yt33xBVY/3tnMxtL1fiDIxYbDWYaZ/eudVw3/PBiZ8G7JwUxXxjW8gU4g6LnOyfGKYHYgw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.6.0.tgz", + "integrity": "sha512-L8UyDwqpTcbkIK5cgwDRDYDoEhQoj8wp8BwsO19w3LB1Z41yEQm2VJyNfAi9DrLP/YTqXqWpKHyZfR9/tFYo1Q==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.0.tgz", + "integrity": "sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.213.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.213.0.tgz", + "integrity": "sha512-3i9NdkET/KvQomeh7UaR/F4r9P25Rx6ooALlWXPIjypcEOUxksCmVu0zA70NBJWlrMW1rPr/LRidFAflLI+s/w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.213.0", + "import-in-the-middle": "^3.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.60.0.tgz", + "integrity": "sha512-q/B2IvoVXRm1M00MvhnzpMN6rKYOszPXVsALi6u0ss4AYHe+TidZEtLW9N1ZhrobI1dSriHnBqqtAOZVAv07sg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.56.0.tgz", + "integrity": "sha512-PKp+sSZ7AfzMvGgO3VCyo1inwNu+q7A1k9X88WK4PQ+S6Hp7eFk8pie+sWHDTaARovmqq5V2osav3lQej2B0nw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.30.0.tgz", + "integrity": "sha512-MXHP2Q38cd2OhzEBKAIXUi9uBlPEYzF6BNJbyjUXBQ6kLaf93kRC41vNMIz0Nl5mnuwK7fDvKT+/lpx7BXRwdg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.61.0.tgz", + "integrity": "sha512-Xdmqo9RZuZlL29Flg8QdwrrX7eW1CZ7wFQPKHyXljNymgKhN1MCsYuqQ/7uxavhSKwAl7WxkTzKhnqpUApLMvQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.32.0.tgz", + "integrity": "sha512-koR6apx0g0wX6RRiPpjA4AFQUQUbXrK16kq4/SZjVp7u5cffJhNkY4TnITxcGA4acGSPYAfx3NHRIv4Khn1axQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.56.0.tgz", + "integrity": "sha512-fg+Jffs6fqrf0uQS0hom7qBFKsbtpBiBl8+Vkc63Gx8xh6pVh+FhagmiO6oM0m3vyb683t1lP7yGYq22SiDnqg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.61.0.tgz", + "integrity": "sha512-pUiVASv6nh2XrerTvlbVHh7vKFzscpgwiQ/xvnZuAIzQ5lRjWVdRPUuXbvZJ/Yq79QsE81TZdJ7z9YsXiss1ew==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.59.0.tgz", + "integrity": "sha512-33wa4mEr+9+ztwdgLor1SeBu4Opz4IsmpcLETXAd3VmBrOjez8uQtrsOhPCa5Vhbm5gzDlMYTgFRLQzf8/YHFA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.213.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.213.0.tgz", + "integrity": "sha512-B978Xsm5XEPGhm1P07grDoaOFLHapJPkOG9h016cJsyWWxmiLnPu2M/4Nrm7UCkHSiLnkXgC+zVGUAIahy8EEA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.0", + "@opentelemetry/instrumentation": "0.213.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.61.0.tgz", + "integrity": "sha512-hsHDadUtAFbws1YSDc1XW0svGFKiUbqv2td1Cby+UAiwvojm1NyBo/taifH0t8CuFZ0x/2SDm0iuTwrM5pnVOg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.22.0.tgz", + "integrity": "sha512-wJU4IBQMUikdJAcTChLFqK5lo+flo7pahqd8DSLv7uMxsdOdAHj6RzKYAm8pPfUS6ItKYutYyuicwKaFwQKsoA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.57.0.tgz", + "integrity": "sha512-vMCSh8kolEm5rRsc+FZeTZymWmIJwc40hjIKnXH4O0Dv/gAkJJIRXCsPX5cPbe0c0j/34+PsENd0HqKruwhVYw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.61.0.tgz", + "integrity": "sha512-lvrfWe9ShK/D2X4brmx8ZqqeWPfRl8xekU0FCn7C1dHm5k6+rTOOi36+4fnaHAP8lig9Ux6XQ1D4RNIpPCt1WQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.57.0.tgz", + "integrity": "sha512-cEqpUocSKJfwDtLYTTJehRLWzkZ2eoePCxfVIgGkGkb83fMB71O+y4MvRHJPbeV2bdoWdOVrl8uO0+EynWhTEA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.66.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.66.0.tgz", + "integrity": "sha512-d7m9QnAY+4TCWI4q1QRkfrc6fo/92VwssaB1DzQfXNRvu51b78P+HJlWP7Qg6N6nkwdb9faMZNBCZJfftmszkw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.59.0.tgz", + "integrity": "sha512-6/jWU+c1NgznkVLDU/2y0bXV2nJo3o9FWZ9mZ9nN6T/JBNRoMnVXZl2FdBmgH+a5MwaWLs5kmRJTP5oUVGIkPw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.59.0.tgz", + "integrity": "sha512-r+V/Fh0sm7Ga8/zk/TI5H5FQRAjwr0RrpfPf8kNIehlsKf12XnvIaZi8ViZkpX0gyPEpLXqzqWD6QHlgObgzZw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.59.0.tgz", + "integrity": "sha512-n9/xrVCRBfG9egVbffnlU1uhr+HX0vF4GgtAB/Bvm48wpFgRidqD8msBMiym1kRYzmpWvJqTxNT47u1MkgBEdw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.65.0.tgz", + "integrity": "sha512-W0zpHEIEuyZ8zvb3njaX9AAbHgPYOsSWVOoWmv1sjVRSF6ZpBqtlxBWbU+6hhq1TFWBeWJOXZ8nZS/PUFpLJYQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.7" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.61.0.tgz", + "integrity": "sha512-JnPexA034/0UJRsvH96B0erQoNOqKJZjE2ZRSw9hiTSC23LzE0nJE/u6D+xqOhgUhRnhhcPHq4MdYtmUdYTF+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.32.0.tgz", + "integrity": "sha512-BQS6gG8RJ1foEqfEZ+wxoqlwfCAzb1ZVG0ad8Gfe4x8T658HJCLGLd4E4NaoQd8EvPfLqOXgzGaE/2U4ytDSWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.23.0.tgz", + "integrity": "sha512-LL0VySzKVR2cJSFVZaTYpZl1XTpBGnfzoQPe2W7McS2267ldsaEIqtQY6VXs2KCXN0poFjze5110PIpxHDaDGg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/semantic-conventions": "^1.24.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.0.tgz", + "integrity": "sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "2.6.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.0.tgz", + "integrity": "sha512-g/OZVkqlxllgFM7qMKqbPV9c1DUPhQ7d4n3pgZFcrnrNft9eJXZM2TNHTPYREJBrtNdRytYyvwjgL5geDKl3EQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/core": "2.6.0", + "@opentelemetry/resources": "2.6.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", + "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "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/@prisma/instrumentation": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.4.2.tgz", + "integrity": "sha512-r9JfchJF1Ae6yAxcaLu/V1TGqBhAuSDe3mRNOssBfx1rMzfZ4fdNvrgUBwyb/TNTGXFxlH9AZix5P257x07nrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.207.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", + "integrity": "sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", + "integrity": "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.207.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@prisma/instrumentation/node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, + "node_modules/@ragestudio/scylla-odm": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@ragestudio/scylla-odm/-/scylla-odm-0.21.0.tgz", + "integrity": "sha512-iqLXvHrg8ZqDfeGcPa9FaVStzytkrPV+9G1mcafySsSHkSvyXQnqEegow6PPkcPeSL9x/WVMU9ZSUokaKZHi/Q==", + "license": "MIT", + "dependencies": { + "long": "^5.3.2" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.0.tgz", + "integrity": "sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.0.tgz", + "integrity": "sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.0.tgz", + "integrity": "sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.0.tgz", + "integrity": "sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.0.tgz", + "integrity": "sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.0.tgz", + "integrity": "sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.0.tgz", + "integrity": "sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.0.tgz", + "integrity": "sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.0.tgz", + "integrity": "sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.0.tgz", + "integrity": "sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.0.tgz", + "integrity": "sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.0.tgz", + "integrity": "sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.0.tgz", + "integrity": "sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.0.tgz", + "integrity": "sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.0.tgz", + "integrity": "sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.0.tgz", + "integrity": "sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.0.tgz", + "integrity": "sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.0.tgz", + "integrity": "sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.0.tgz", + "integrity": "sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.0.tgz", + "integrity": "sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.0.tgz", + "integrity": "sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.0.tgz", + "integrity": "sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.0.tgz", + "integrity": "sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.0.tgz", + "integrity": "sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.0.tgz", + "integrity": "sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sentry/core": { + "version": "10.44.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.44.0.tgz", + "integrity": "sha512-aa7CiDaNFZvHpqd97LJhuskolfJ/4IH5xyuVVLnv7l6B0v9KTwskPUxb0tH1ej3FxuzfH+i8iTiTFuqpfHS3QA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "10.44.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.44.0.tgz", + "integrity": "sha512-q+/WR9ZeF9Af8uyehOj2tQQOa7LH07mJfOuDus5X6G6cLuugdRUGUBB5Qhw+J/ULSxbzGADBZv6AYOyoGaNx7w==", + "license": "MIT", + "dependencies": { + "@fastify/otel": "0.17.1", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^2.6.0", + "@opentelemetry/core": "^2.6.0", + "@opentelemetry/instrumentation": "^0.213.0", + "@opentelemetry/instrumentation-amqplib": "0.60.0", + "@opentelemetry/instrumentation-connect": "0.56.0", + "@opentelemetry/instrumentation-dataloader": "0.30.0", + "@opentelemetry/instrumentation-express": "0.61.0", + "@opentelemetry/instrumentation-fs": "0.32.0", + "@opentelemetry/instrumentation-generic-pool": "0.56.0", + "@opentelemetry/instrumentation-graphql": "0.61.0", + "@opentelemetry/instrumentation-hapi": "0.59.0", + "@opentelemetry/instrumentation-http": "0.213.0", + "@opentelemetry/instrumentation-ioredis": "0.61.0", + "@opentelemetry/instrumentation-kafkajs": "0.22.0", + "@opentelemetry/instrumentation-knex": "0.57.0", + "@opentelemetry/instrumentation-koa": "0.61.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.57.0", + "@opentelemetry/instrumentation-mongodb": "0.66.0", + "@opentelemetry/instrumentation-mongoose": "0.59.0", + "@opentelemetry/instrumentation-mysql": "0.59.0", + "@opentelemetry/instrumentation-mysql2": "0.59.0", + "@opentelemetry/instrumentation-pg": "0.65.0", + "@opentelemetry/instrumentation-redis": "0.61.0", + "@opentelemetry/instrumentation-tedious": "0.32.0", + "@opentelemetry/instrumentation-undici": "0.23.0", + "@opentelemetry/resources": "^2.6.0", + "@opentelemetry/sdk-trace-base": "^2.6.0", + "@opentelemetry/semantic-conventions": "^1.40.0", + "@prisma/instrumentation": "7.4.2", + "@sentry/core": "10.44.0", + "@sentry/node-core": "10.44.0", + "@sentry/opentelemetry": "10.44.0", + "import-in-the-middle": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "10.44.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.44.0.tgz", + "integrity": "sha512-jUGsadMrvZ08UMbqJBfjFFMk1k3VbyxfUypf0iDGGgyLmuHotYQPo/5aND+o2KxMDXR60LwcQrMoZFpanK6jXQ==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.44.0", + "@sentry/opentelemetry": "10.44.0", + "import-in-the-middle": "^3.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/context-async-hooks": { + "optional": true + }, + "@opentelemetry/core": { + "optional": true + }, + "@opentelemetry/instrumentation": { + "optional": true + }, + "@opentelemetry/resources": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "@opentelemetry/semantic-conventions": { + "optional": true + } + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "10.44.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.44.0.tgz", + "integrity": "sha512-zP4vP8tBxjlmxQ4VcWOwZ0b3lPUxlYPg9FqJwANm9SRJN+7V5psm8TIaAtu9uqtIcJMRHdXkOM4cAggNiLk0KA==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.44.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "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==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.3.tgz", + "integrity": "sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "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/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/luxon": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz", + "integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==", + "license": "MIT" + }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" + } + }, + "node_modules/@types/pg": { + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", + "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, + "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/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "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/@typescript-eslint/eslint-plugin": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", + "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/type-utils": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.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.57.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", + "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@opentelemetry/api-logs": "0.213.0", - "import-in-the-middle": "^3.0.0", - "require-in-the-middle": "^8.0.0" + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "debug": "^4.4.3" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@opentelemetry/instrumentation-amqplib": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.60.0.tgz", - "integrity": "sha512-q/B2IvoVXRm1M00MvhnzpMN6rKYOszPXVsALi6u0ss4AYHe+TidZEtLW9N1ZhrobI1dSriHnBqqtAOZVAv07sg==", - "license": "Apache-2.0", + "node_modules/@typescript-eslint/project-service": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", + "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0" + "@typescript-eslint/tsconfig-utils": "^8.57.1", + "@typescript-eslint/types": "^8.57.1", + "debug": "^4.4.3" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@opentelemetry/instrumentation-connect": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.56.0.tgz", - "integrity": "sha512-PKp+sSZ7AfzMvGgO3VCyo1inwNu+q7A1k9X88WK4PQ+S6Hp7eFk8pie+sWHDTaARovmqq5V2osav3lQej2B0nw==", - "license": "Apache-2.0", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", + "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/connect": "3.4.38" + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", + "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "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.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", + "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.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.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", + "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.1", + "@typescript-eslint/tsconfig-utils": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.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.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", + "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1" + }, + "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.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", + "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.1", + "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" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", + "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", + "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.4", + "vitest": "3.2.4" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "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", + "engines": { + "node": ">=18" + } + }, + "node_modules/@vitest/coverage-v8/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/@vitest/coverage-v8/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vitest/coverage-v8/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" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@opentelemetry/instrumentation-dataloader": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.30.0.tgz", - "integrity": "sha512-MXHP2Q38cd2OhzEBKAIXUi9uBlPEYzF6BNJbyjUXBQ6kLaf93kRC41vNMIz0Nl5mnuwK7fDvKT+/lpx7BXRwdg==", - "license": "Apache-2.0", + "node_modules/@vitest/coverage-v8/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": { - "@opentelemetry/instrumentation": "^0.213.0" + "brace-expansion": "^2.0.2" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@opentelemetry/instrumentation-express": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.61.0.tgz", - "integrity": "sha512-Xdmqo9RZuZlL29Flg8QdwrrX7eW1CZ7wFQPKHyXljNymgKhN1MCsYuqQ/7uxavhSKwAl7WxkTzKhnqpUApLMvQ==", - "license": "Apache-2.0", + "node_modules/@vitest/coverage-v8/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": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" }, "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "node": ">=10" } }, - "node_modules/@opentelemetry/instrumentation-fs": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.32.0.tgz", - "integrity": "sha512-koR6apx0g0wX6RRiPpjA4AFQUQUbXrK16kq4/SZjVp7u5cffJhNkY4TnITxcGA4acGSPYAfx3NHRIv4Khn1axQ==", - "license": "Apache-2.0", + "node_modules/@vitest/coverage-v8/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/@vitest/coverage-v8/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": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=16 || 14 >=14.18" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@opentelemetry/instrumentation-generic-pool": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.56.0.tgz", - "integrity": "sha512-fg+Jffs6fqrf0uQS0hom7qBFKsbtpBiBl8+Vkc63Gx8xh6pVh+FhagmiO6oM0m3vyb683t1lP7yGYq22SiDnqg==", - "license": "Apache-2.0", + "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": { - "@opentelemetry/instrumentation": "^0.213.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^10.2.2" }, "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "node": ">=18" } }, - "node_modules/@opentelemetry/instrumentation-graphql": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.61.0.tgz", - "integrity": "sha512-pUiVASv6nh2XrerTvlbVHh7vKFzscpgwiQ/xvnZuAIzQ5lRjWVdRPUuXbvZJ/Yq79QsE81TZdJ7z9YsXiss1ew==", - "license": "Apache-2.0", + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-hapi": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.59.0.tgz", - "integrity": "sha512-33wa4mEr+9+ztwdgLor1SeBu4Opz4IsmpcLETXAd3VmBrOjez8uQtrsOhPCa5Vhbm5gzDlMYTgFRLQzf8/YHFA==", - "license": "Apache-2.0", + "node_modules/@vitest/expect/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": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "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.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "node": ">=18" } }, - "node_modules/@opentelemetry/instrumentation-http": { - "version": "0.213.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.213.0.tgz", - "integrity": "sha512-B978Xsm5XEPGhm1P07grDoaOFLHapJPkOG9h016cJsyWWxmiLnPu2M/4Nrm7UCkHSiLnkXgC+zVGUAIahy8EEA==", - "license": "Apache-2.0", + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/core": "2.6.0", - "@opentelemetry/instrumentation": "0.213.0", - "@opentelemetry/semantic-conventions": "^1.29.0", - "forwarded-parse": "2.1.2" + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "funding": { + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@opentelemetry/instrumentation-ioredis": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.61.0.tgz", - "integrity": "sha512-hsHDadUtAFbws1YSDc1XW0svGFKiUbqv2td1Cby+UAiwvojm1NyBo/taifH0t8CuFZ0x/2SDm0iuTwrM5pnVOg==", - "license": "Apache-2.0", + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/redis-common": "^0.38.2", - "@opentelemetry/semantic-conventions": "^1.33.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "tinyrainbow": "^2.0.0" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-kafkajs": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.22.0.tgz", - "integrity": "sha512-wJU4IBQMUikdJAcTChLFqK5lo+flo7pahqd8DSLv7uMxsdOdAHj6RzKYAm8pPfUS6ItKYutYyuicwKaFwQKsoA==", - "license": "Apache-2.0", + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.30.0" + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-knex": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.57.0.tgz", - "integrity": "sha512-vMCSh8kolEm5rRsc+FZeTZymWmIJwc40hjIKnXH4O0Dv/gAkJJIRXCsPX5cPbe0c0j/34+PsENd0HqKruwhVYw==", - "license": "Apache-2.0", + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.1" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-koa": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.61.0.tgz", - "integrity": "sha512-lvrfWe9ShK/D2X4brmx8ZqqeWPfRl8xekU0FCn7C1dHm5k6+rTOOi36+4fnaHAP8lig9Ux6XQ1D4RNIpPCt1WQ==", - "license": "Apache-2.0", + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.36.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "tinyspy": "^4.0.3" }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-lru-memoizer": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.57.0.tgz", - "integrity": "sha512-cEqpUocSKJfwDtLYTTJehRLWzkZ2eoePCxfVIgGkGkb83fMB71O+y4MvRHJPbeV2bdoWdOVrl8uO0+EynWhTEA==", - "license": "Apache-2.0", + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@opentelemetry/instrumentation-mongodb": { - "version": "0.66.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.66.0.tgz", - "integrity": "sha512-d7m9QnAY+4TCWI4q1QRkfrc6fo/92VwssaB1DzQfXNRvu51b78P+HJlWP7Qg6N6nkwdb9faMZNBCZJfftmszkw==", - "license": "Apache-2.0", + "node_modules/7zip-bin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "license": "MIT" + }, + "node_modules/7zip-min": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.5.tgz", + "integrity": "sha512-S+FzNwJFKF5LgQYs+hPQo+qeffdi+259Ak63rWEfkHP9arsU8gbe5K+4HscuWN1ih1lP1gTjDNPddbU0qhPtHQ==", + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0" + "7zip-bin": "5.1.1" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@opentelemetry/instrumentation-mongoose": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.59.0.tgz", - "integrity": "sha512-6/jWU+c1NgznkVLDU/2y0bXV2nJo3o9FWZ9mZ9nN6T/JBNRoMnVXZl2FdBmgH+a5MwaWLs5kmRJTP5oUVGIkPw==", - "license": "Apache-2.0", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "node": ">=8" } }, - "node_modules/@opentelemetry/instrumentation-mysql": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.59.0.tgz", - "integrity": "sha512-r+V/Fh0sm7Ga8/zk/TI5H5FQRAjwr0RrpfPf8kNIehlsKf12XnvIaZi8ViZkpX0gyPEpLXqzqWD6QHlgObgzZw==", - "license": "Apache-2.0", + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@types/mysql": "2.15.27" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@opentelemetry/instrumentation-mysql2": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.59.0.tgz", - "integrity": "sha512-n9/xrVCRBfG9egVbffnlU1uhr+HX0vF4GgtAB/Bvm48wpFgRidqD8msBMiym1kRYzmpWvJqTxNT47u1MkgBEdw==", - "license": "Apache-2.0", + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@opentelemetry/sql-common": "^0.41.2" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "ajv": "^8.0.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/@opentelemetry/instrumentation-pg": { - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.65.0.tgz", - "integrity": "sha512-W0zpHEIEuyZ8zvb3njaX9AAbHgPYOsSWVOoWmv1sjVRSF6ZpBqtlxBWbU+6hhq1TFWBeWJOXZ8nZS/PUFpLJYQ==", - "license": "Apache-2.0", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.34.0", - "@opentelemetry/sql-common": "^0.41.2", - "@types/pg": "8.15.6", - "@types/pg-pool": "2.0.7" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@opentelemetry/instrumentation-redis": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.61.0.tgz", - "integrity": "sha512-JnPexA034/0UJRsvH96B0erQoNOqKJZjE2ZRSw9hiTSC23LzE0nJE/u6D+xqOhgUhRnhhcPHq4MdYtmUdYTF+Q==", - "license": "Apache-2.0", + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "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": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/redis-common": "^0.38.2", - "@opentelemetry/semantic-conventions": "^1.27.0" + "type-fest": "^0.21.3" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=8" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@opentelemetry/instrumentation-tedious": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.32.0.tgz", - "integrity": "sha512-BQS6gG8RJ1foEqfEZ+wxoqlwfCAzb1ZVG0ad8Gfe4x8T658HJCLGLd4E4NaoQd8EvPfLqOXgzGaE/2U4ytDSWA==", - "license": "Apache-2.0", + "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/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@types/tedious": "^4.0.14" + "color-convert": "^2.0.1" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=8" }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@opentelemetry/instrumentation-undici": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.23.0.tgz", - "integrity": "sha512-LL0VySzKVR2cJSFVZaTYpZl1XTpBGnfzoQPe2W7McS2267ldsaEIqtQY6VXs2KCXN0poFjze5110PIpxHDaDGg==", - "license": "Apache-2.0", + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/semantic-conventions": "^1.24.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.7.0" + "node": ">= 8" } }, - "node_modules/@opentelemetry/redis-common": { - "version": "0.38.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", - "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", - "license": "Apache-2.0", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/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": "^18.19.0 || >=20.6.0" + "node": ">=12" } }, - "node_modules/@opentelemetry/resources": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.0.tgz", - "integrity": "sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==", - "license": "Apache-2.0", - "peer": true, + "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": { - "@opentelemetry/core": "2.6.0", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" } }, - "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.0.tgz", - "integrity": "sha512-g/OZVkqlxllgFM7qMKqbPV9c1DUPhQ7d4n3pgZFcrnrNft9eJXZM2TNHTPYREJBrtNdRytYyvwjgL5geDKl3EQ==", - "license": "Apache-2.0", - "peer": true, + "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/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/auth": { + "resolved": "services/auth", + "link": true + }, + "node_modules/axios": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "license": "MIT", "dependencies": { - "@opentelemetry/core": "2.6.0", - "@opentelemetry/resources": "2.6.0", - "@opentelemetry/semantic-conventions": "^1.29.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/b4a": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", + "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" + "@babel/core": "^7.8.0" } }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", - "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", - "license": "Apache-2.0", - "peer": true, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, "engines": { - "node": ">=14" + "node": ">=8" } }, - "node_modules/@opentelemetry/sql-common": { - "version": "0.41.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", - "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", - "license": "Apache-2.0", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@opentelemetry/core": "^2.0.0" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@prisma/instrumentation": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.4.2.tgz", - "integrity": "sha512-r9JfchJF1Ae6yAxcaLu/V1TGqBhAuSDe3mRNOssBfx1rMzfZ4fdNvrgUBwyb/TNTGXFxlH9AZix5P257x07nrg==", - "license": "Apache-2.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": { - "@opentelemetry/instrumentation": "^0.207.0" + "@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": { - "@opentelemetry/api": "^1.8" + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, - "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", - "integrity": "sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==", - "license": "Apache-2.0", + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", "dependencies": { - "@opentelemetry/api": "^1.3.0" + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", - "integrity": "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==", + "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==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.1.tgz", + "integrity": "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.207.0", - "import-in-the-middle": "^2.0.0", - "require-in-the-middle": "^8.0.0" + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { - "node": "^18.19.0 || >=20.6.0" + "bare": ">=1.16.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.3.0" + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } } }, - "node_modules/@prisma/instrumentation/node_modules/import-in-the-middle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", - "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", "license": "Apache-2.0", - "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" - } - }, - "node_modules/@sentry/core": { - "version": "10.44.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.44.0.tgz", - "integrity": "sha512-aa7CiDaNFZvHpqd97LJhuskolfJ/4IH5xyuVVLnv7l6B0v9KTwskPUxb0tH1ej3FxuzfH+i8iTiTFuqpfHS3QA==", - "license": "MIT", "engines": { - "node": ">=18" + "bare": ">=1.14.0" } }, - "node_modules/@sentry/node": { - "version": "10.44.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.44.0.tgz", - "integrity": "sha512-q+/WR9ZeF9Af8uyehOj2tQQOa7LH07mJfOuDus5X6G6cLuugdRUGUBB5Qhw+J/ULSxbzGADBZv6AYOyoGaNx7w==", - "license": "MIT", + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", "dependencies": { - "@fastify/otel": "0.17.1", - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^2.6.0", - "@opentelemetry/core": "^2.6.0", - "@opentelemetry/instrumentation": "^0.213.0", - "@opentelemetry/instrumentation-amqplib": "0.60.0", - "@opentelemetry/instrumentation-connect": "0.56.0", - "@opentelemetry/instrumentation-dataloader": "0.30.0", - "@opentelemetry/instrumentation-express": "0.61.0", - "@opentelemetry/instrumentation-fs": "0.32.0", - "@opentelemetry/instrumentation-generic-pool": "0.56.0", - "@opentelemetry/instrumentation-graphql": "0.61.0", - "@opentelemetry/instrumentation-hapi": "0.59.0", - "@opentelemetry/instrumentation-http": "0.213.0", - "@opentelemetry/instrumentation-ioredis": "0.61.0", - "@opentelemetry/instrumentation-kafkajs": "0.22.0", - "@opentelemetry/instrumentation-knex": "0.57.0", - "@opentelemetry/instrumentation-koa": "0.61.0", - "@opentelemetry/instrumentation-lru-memoizer": "0.57.0", - "@opentelemetry/instrumentation-mongodb": "0.66.0", - "@opentelemetry/instrumentation-mongoose": "0.59.0", - "@opentelemetry/instrumentation-mysql": "0.59.0", - "@opentelemetry/instrumentation-mysql2": "0.59.0", - "@opentelemetry/instrumentation-pg": "0.65.0", - "@opentelemetry/instrumentation-redis": "0.61.0", - "@opentelemetry/instrumentation-tedious": "0.32.0", - "@opentelemetry/instrumentation-undici": "0.23.0", - "@opentelemetry/resources": "^2.6.0", - "@opentelemetry/sdk-trace-base": "^2.6.0", - "@opentelemetry/semantic-conventions": "^1.40.0", - "@prisma/instrumentation": "7.4.2", - "@sentry/core": "10.44.0", - "@sentry/node-core": "10.44.0", - "@sentry/opentelemetry": "10.44.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" + "bare-os": "^3.0.1" } }, - "node_modules/@sentry/node-core": { - "version": "10.44.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.44.0.tgz", - "integrity": "sha512-jUGsadMrvZ08UMbqJBfjFFMk1k3VbyxfUypf0iDGGgyLmuHotYQPo/5aND+o2KxMDXR60LwcQrMoZFpanK6jXQ==", - "license": "MIT", + "node_modules/bare-stream": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", + "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", + "license": "Apache-2.0", "dependencies": { - "@sentry/core": "10.44.0", - "@sentry/opentelemetry": "10.44.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" + "streamx": "^2.21.0", + "teex": "^1.0.1" }, "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/instrumentation": ">=0.57.1 <1", - "@opentelemetry/resources": "^1.30.1 || ^2.1.0", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" + "bare-buffer": "*", + "bare-events": "*" }, "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@opentelemetry/context-async-hooks": { - "optional": true - }, - "@opentelemetry/core": { - "optional": true - }, - "@opentelemetry/instrumentation": { + "bare-buffer": { "optional": true }, - "@opentelemetry/resources": { + "bare-events": { "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@opentelemetry/sdk-trace-base": { - "optional": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@opentelemetry/semantic-conventions": { - "optional": true + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@sentry/opentelemetry": { - "version": "10.44.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.44.0.tgz", - "integrity": "sha512-zP4vP8tBxjlmxQ4VcWOwZ0b3lPUxlYPg9FqJwANm9SRJN+7V5psm8TIaAtu9uqtIcJMRHdXkOM4cAggNiLk0KA==", + "node_modules/bcrypt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", + "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==", + "hasInstallScript": true, "license": "MIT", "dependencies": { - "@sentry/core": "10.44.0" + "node-addon-api": "^8.3.0", + "node-gyp-build": "^4.8.4" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" + "node": ">= 18" } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "license": "Apache-2.0" }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "dependencies": { - "@sinonjs/commons": "^3.0.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/@sinonjs/samsam": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.3.tgz", - "integrity": "sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/block-stream2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz", + "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==", + "license": "MIT", "dependencies": { - "@sinonjs/commons": "^3.0.1", - "type-detect": "^4.1.0" + "readable-stream": "^3.4.0" } }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": ">=4" + "node": "18 || 20 || >=22" } }, - "node_modules/@tokenizer/inflate": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", - "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.4.3", - "token-types": "^6.1.1" + "fill-range": "^7.1.1" }, "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node": ">=8" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "node_modules/browser-or-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", + "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==", "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/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", + "peer": true, "dependencies": { - "@types/node": "*" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "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" + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "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": "MIT" + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" + "node_modules/bson": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz", + "integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } }, - "node_modules/@types/mysql": { - "version": "2.15.27", - "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", - "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "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": { - "@types/node": "*" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@types/pg": { - "version": "8.15.6", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", - "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.1.0.tgz", + "integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==", + "hasInstallScript": true, "license": "MIT", + "optional": true, "dependencies": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^2.2.0" + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" } }, - "node_modules/@types/pg-pool": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", - "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", + "node_modules/bullmq": { + "version": "5.76.5", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.76.5.tgz", + "integrity": "sha512-2OKJP2+ckc+TygsWdxxeZYYgM9xYnVXgIAx+perflhamZ6FEBu/cSrvpqM8++fJI5OgsIFLfxA9UO7BDZ74Inw==", "license": "MIT", "dependencies": { - "@types/pg": "*" + "cron-parser": "4.9.0", + "ioredis": "5.10.1", + "msgpackr": "1.11.12", + "node-abort-controller": "3.1.1", + "semver": "7.7.4", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=12.22.0" } }, - "node_modules/@types/tedious": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", - "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", - "license": "MIT", + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { - "@types/node": "*" + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", - "license": "MIT" + "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/@types/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "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", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { - "@types/webidl-conversions": "*" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", - "dev": true, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=6" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", - "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "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", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", - "debug": "^4.4.3" - }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10" }, "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.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "node_modules/caniuse-lite": { + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", - "debug": "^4.4.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "has-flag": "^4.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=8" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "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": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "node": ">=10" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "node_modules/chats": { + "resolved": "services/chats", + "link": true + }, + "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": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "readdirp": "^4.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 14.16.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chokidar/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "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==", + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "engines": { + "node": ">=12" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "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", - "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.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.0.0" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "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": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "color-convert": "^2.0.1", + "color-string": "^1.9.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.0.0" + "node": ">=12.5.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", - "dev": true, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "eslint-visitor-keys": "^5.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=7.0.0" } }, - "node_modules/7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/7zip-min": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.5.tgz", - "integrity": "sha512-S+FzNwJFKF5LgQYs+hPQo+qeffdi+259Ak63rWEfkHP9arsU8gbe5K+4HscuWN1ih1lP1gTjDNPddbU0qhPtHQ==", + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "license": "MIT", "dependencies": { - "7zip-bin": "5.1.1" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" + "engines": { + "node": ">=18" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">=6.6.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", "license": "MIT", - "peerDependencies": { - "acorn": "^8" + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/adm-zip": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", - "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, "engines": { - "node": ">=12.0" + "node": ">=12.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/cross-env": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", + "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", "license": "MIT", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "@epic-web/invariant": "^1.0.0", + "cross-spawn": "^7.0.6" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" }, "engines": { - "node": ">=8" + "node": ">=20" } }, - "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "dev": true, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "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" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">= 8" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "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", + "engines": { + "node": ">= 12" + } + }, + "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": { - "ajv": "^8.0.0" + "ms": "^2.1.3" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": ">=6.0" }, "peerDependenciesMeta": { - "ajv": { + "supports-color": { "optional": true } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, "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" + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "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, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "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": "Python-2.0" - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/auth": { - "resolved": "services/auth", - "link": true - }, - "node_modules/axios": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", - "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/b4a": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", - "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", - "license": "Apache-2.0", "peerDependencies": { - "react-native-b4a": "*" + "babel-plugin-macros": "^3.1.0" }, "peerDependenciesMeta": { - "react-native-b4a": { + "babel-plugin-macros": { "optional": true } } }, - "node_modules/babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "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", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "engines": { + "node": ">=6" } }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", "license": "MIT" }, - "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==", + "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", "engines": { - "node": "18 || 20 || >=22" + "node": ">=4.0.0" } }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } + "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==", + "dev": true, + "license": "MIT" }, - "node_modules/bare-fs": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.4.tgz", - "integrity": "sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/bare-os": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", - "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", - "license": "Apache-2.0", - "optional": true, + "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": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^3.0.1" + "node": ">=0.4.0" } }, - "node_modules/bare-stream": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", - "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.21.0", - "teex": "^1.0.1" - }, - "peerDependencies": { - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" }, - "node_modules/bare-url": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", - "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-path": "^3.0.0" + "engines": { + "node": ">=0.10" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/bcrypt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", - "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==", - "hasInstallScript": true, + "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", - "dependencies": { - "node-addon-api": "^8.3.0", - "node-gyp-build": "^4.8.4" - }, "engines": { - "node": ">= 18" + "node": ">= 0.8" } }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "license": "Apache-2.0" + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "license": "ISC" }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "engines": { + "node": ">=6" } }, - "node_modules/block-stream2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz", - "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", - "dependencies": { - "readable-stream": "^3.4.0" + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", "engines": { - "node": "18 || 20 || >=22" + "node": ">=8" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "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", - "dependencies": { - "fill-range": "^7.1.1" - }, "engines": { "node": ">=8" } }, - "node_modules/browser-or-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", - "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==", - "license": "MIT" + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/bson": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz", - "integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==", - "license": "Apache-2.0", + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", "engines": { - "node": ">=20.19.0" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "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" - } - ], + "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": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/buffer-crc32": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", - "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "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_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.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" + "node_modules/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/bufferutil": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.1.0.tgz", - "integrity": "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==", - "hasInstallScript": true, + "node_modules/ems": { + "resolved": "services/ems", + "link": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, "engines": { - "node": ">=6.14.2" + "node": ">= 0.8" } }, - "node_modules/bullmq": { - "version": "5.71.0", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.71.0.tgz", - "integrity": "sha512-aeNWh4drsafSKnAJeiNH/nZP/5O8ZdtdMbnOPZmpjXj7NZUP5YC901U3bIH41iZValm7d1i3c34ojv7q31m30w==", + "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": { - "cron-parser": "4.9.0", - "ioredis": "5.9.3", - "msgpackr": "1.11.5", - "node-abort-controller": "3.1.1", - "semver": "7.7.4", - "tslib": "2.8.1", - "uuid": "11.1.0" + "once": "^1.4.0" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "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": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" + "is-arrayish": "^0.2.1" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "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", "engines": { - "node": ">= 0.8" + "node": ">= 0.4" } }, - "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", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "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", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, "engines": { "node": ">= 0.4" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "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/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "dependencies": { + "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "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", - "engines": { - "node": ">=10" + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.4" } }, - "node_modules/cassandra-driver": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/cassandra-driver/-/cassandra-driver-4.8.0.tgz", - "integrity": "sha512-HritfMGq9V7SuESeSodHvArs0mLuMk7uh+7hQK2lqdvXrvm50aWxb4RPxkK3mPDdsgHjJ427xNRFITMH2ei+Sw==", - "license": "Apache-2.0", - "dependencies": { - "@types/node": "^18.11.18", - "adm-zip": "~0.5.10", - "long": "~5.2.3" + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" }, "engines": { "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" } }, - "node_modules/cassandra-driver/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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" + "engines": { + "node": ">=6" } }, - "node_modules/cassandra-driver/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/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/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "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==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chats": { - "resolved": "services/chats", - "link": true - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "node_modules/eslint": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz", + "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "get-func-name": "^2.0.2" + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.3", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.1", + "@eslint/plugin-kit": "^0.6.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.1.1", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": "*" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/check-types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz", - "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==", - "license": "MIT" - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "license": "MIT", + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "readdirp": "^4.0.1" + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 14.16.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://opencollective.com/eslint" } }, - "node_modules/chokidar/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "license": "MIT", + "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": ">= 14.18.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://opencollective.com/eslint" } }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", + "node_modules/espree": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.1.tgz", + "integrity": "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", - "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" + } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "license": "MIT", + "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==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, "engines": { - "node": ">=6" + "node": ">=0.10" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "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": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=12" + "node": ">=4.0" } }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "license": "Apache-2.0", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "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": "MIT", "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" + "@types/estree": "^1.0.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/eta/-/eta-4.5.1.tgz", + "integrity": "sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ==", "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/bgub/eta?sponsor=1" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "bare-events": "^2.7.0" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "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": { - "delayed-stream": "~1.0.0" + "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": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, "engines": { - "node": ">= 6" + "node": ">= 0.8.0" } }, - "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", - "license": "MIT", + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=6" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=12.0.0" } }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.3.0.tgz", + "integrity": "sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT", - "engines": { - "node": ">=6.6.0" + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0", + "json-schema-ref-resolver": "^3.0.0", + "rfdc": "^1.2.0" } }, - "node_modules/cookies": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", - "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "node_modules/fast-json-stringify/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { - "depd": "~2.0.0", - "keygrip": "~1.1.0" + "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": ">= 0.8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true, + "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "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/cron-parser": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", - "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-builder": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.9.tgz", + "integrity": "sha512-jcyKVSEX13iseJqg7n/KWw+xnu/7fdrZ333Fac54KjHDIELVCfDDJXYIm6DTJ0Su4gSzrhqiK0DzY/wZbF40mw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", "dependencies": { - "luxon": "^3.2.1" - }, - "engines": { - "node": ">=12.0.0" + "path-expression-matcher": "^1.1.3" } }, - "node_modules/cross-env": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", - "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", + "node_modules/fast-xml-parser": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz", + "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", "dependencies": { - "@epic-web/invariant": "^1.0.0", - "cross-spawn": "^7.0.6" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.7", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { - "cross-env": "dist/bin/cross-env.js", - "cross-env-shell": "dist/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=20" + "fxparser": "src/cli/cli.js" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", + "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": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "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", - "engines": { - "node": ">= 12" + "bser": "2.1.1" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "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": { - "ms": "^2.1.3" + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^12.20 || >= 14.13" } }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "flat-cache": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=16.0.0" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "node_modules/file-type": { + "version": "21.3.3", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.3.tgz", + "integrity": "sha512-pNwbwz8c3aZ+GvbJnIsCnDjKvgCZLHxkFWLEFxU3RMa+Ey++ZSEfisvsWQMcdys6PpxQjWUOIDi1fifXsW3YRg==", "license": "MIT", "dependencies": { - "mimic-response": "^3.1.0" + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" }, "engines": { - "node": ">=10" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/deep-diff": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", - "integrity": "sha512-yVn6RZmHiGnxRKR9sJb3iVV2XTF1Ghh2DiWRZ3dMnGc43yUdWWF/kX6lQyk3+P84iprfWKU/8zFTrlkvtFm1ug==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT" + "node_modules/files": { + "resolved": "services/files", + "link": true }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { - "type-detect": "^4.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", - "license": "MIT" - }, - "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==", + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">=0.10.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/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" - }, - "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", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.10" + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" } }, - "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==", + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, "engines": { - "node": ">= 0.8" + "node": ">=16" } }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0" + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, "license": "ISC" }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "node_modules/fluent-ffmpeg": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz", + "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "license": "MIT", + "dependencies": { + "async": "^0.2.9", + "which": "^1.1.1" + }, "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node_modules/fluent-ffmpeg/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/diff": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "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": "BSD-3-Clause", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">=0.3.1" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", + "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": ">=12" + "node": ">=14" }, "funding": { - "url": "https://dotenvx.com" + "url": "https://github.com/sponsors/isaacs" } }, - "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/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "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": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "fetch-blob": "^3.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=12.20.0" } }, - "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_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "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==", + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, - "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==", + "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": "MIT" - }, - "node_modules/ems": { - "resolved": "services/ems", - "link": true + "license": "ISC" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6.9.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==", - "license": "MIT", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "es-errors": "^1.3.0" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/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", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "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": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "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/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "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/globals": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz", - "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", - "dev": true, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.3", - "@eslint/config-helpers": "^0.5.2", - "@eslint/core": "^1.1.1", - "@eslint/plugin-kit": "^0.6.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.2", - "eslint-visitor-keys": "^5.0.1", - "espree": "^11.1.1", - "esquery": "^1.7.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" + "engines": { + "node": ">= 0.4" }, - "bin": { - "eslint": "bin/eslint.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/groups": { + "resolved": "services/groups", + "link": true + }, + "node_modules/h264-profile-level-id": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/h264-profile-level-id/-/h264-profile-level-id-2.3.2.tgz", + "integrity": "sha512-hnq1UDlw7WGJV6GCr/g7wnkHYUjdAY2bis9rgn2JqSdQS2WfVvnt1ZE9g8nTguracodf5LLKZOwURsDN49YtBQ==", + "license": "ISC", + "dependencies": { + "debug": "^4.4.3" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=20" }, "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } + "type": "opencollective", + "url": "https://opencollective.com/mediasoup" } }, - "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "license": "MIT", "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=0.4.7" }, - "funding": { - "url": "https://opencollective.com/eslint" + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "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/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.1.tgz", - "integrity": "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { - "acorn": "^8.16.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" + "has-symbols": "^1.0.3" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { - "estraverse": "^5.1.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=0.10" + "node": ">= 0.4" } }, - "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==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" }, "engines": { - "node": ">=4.0" + "node": ">= 0.8" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">= 0.6" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/eta": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/eta/-/eta-4.5.1.tgz", - "integrity": "sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ==", + "node_modules/http-assert/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "license": "MIT", "engines": { - "node": ">=20" + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" }, "funding": { - "url": "https://github.com/bgub/eta?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" - }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "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/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", "dependencies": { - "bare-events": "^2.7.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "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==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 4" } }, - "node_modules/express-cassandra": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/express-cassandra/-/express-cassandra-2.9.1.tgz", - "integrity": "sha512-D63gNbm3O1mQmN10PVKvZyOQEU+gd9nE4KvOkXNLu8EkUbiCXtKTxx2LPH7pQzepJfRaP2szr6JsNqI5/mCb7A==", - "license": "LGPL-3.0", - "dependencies": { - "async": "^2.6.4", - "babel-polyfill": "^6.26.0", - "bluebird": "^3.4.6", - "cassandra-driver": "^4.6.2", - "chai": "^4.1.2", - "check-types": "^7.4.0", - "debug": "^3.1.0", - "deep-diff": "^0.3.4", - "JSONStream": "^1.3.1", - "lodash": "^4.17.15", - "object-hash": "1.1.4", - "readdirp": "^2.1.0", - "readline-sync": "^1.4.4", - "semver": "^5.4.1" + "node_modules/import-in-the-middle": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.1.tgz", + "integrity": "sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" }, "engines": { - "node": ">= 12" + "node": ">=18" } }, - "node_modules/express-cassandra/node_modules/chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "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": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/express-cassandra/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "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", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/express-cassandra/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=0.8.19" } }, - "node_modules/express-cassandra/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "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": "MIT" - }, - "node_modules/fast-json-stringify": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.3.0.tgz", - "integrity": "sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT", + "license": "ISC", "dependencies": { - "@fastify/merge-json-schemas": "^0.2.0", - "ajv": "^8.12.0", - "ajv-formats": "^3.0.1", - "fast-uri": "^3.0.0", - "json-schema-ref-resolver": "^3.0.0", - "rfdc": "^1.2.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/fast-json-stringify/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/ioredis": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.10.1.tgz", + "integrity": "sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==", "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" + "@ioredis/commands": "1.5.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, - "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" + "node_modules/ipaddr.js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + } }, - "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, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, "license": "MIT", "dependencies": { - "path-expression-matcher": "^1.1.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-xml-parser": { - "version": "5.5.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz", - "integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", - "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.1.3", - "strnum": "^2.1.2" - }, - "bin": { - "fxparser": "src/cli/cli.js" + "engines": { + "node": ">=0.10.0" } }, - "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" - } - ], + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">=8" } }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "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", - "dependencies": { - "flat-cache": "^4.0.0" - }, "engines": { - "node": ">=16.0.0" + "node": ">=6" } }, - "node_modules/file-type": { - "version": "21.3.3", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.3.tgz", - "integrity": "sha512-pNwbwz8c3aZ+GvbJnIsCnDjKvgCZLHxkFWLEFxU3RMa+Ey++ZSEfisvsWQMcdys6PpxQjWUOIDi1fifXsW3YRg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { - "@tokenizer/inflate": "^0.4.1", - "strtok3": "^10.3.4", - "token-types": "^6.1.1", - "uint8array-extras": "^1.4.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/files": { - "resolved": "services/files", - "link": true + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "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", - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { "node": ">=8" } }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "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==", + "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", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3665,661 +7312,809 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" + "engines": { + "node": ">=8" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "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": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "@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": ">=16" + "node": ">=10" } }, - "node_modules/flatbuffers": { - "version": "25.9.23", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", - "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", - "license": "Apache-2.0" - }, - "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "license": "ISC" - }, - "node_modules/fluent-ffmpeg": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz", - "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "async": "^0.2.9", - "which": "^1.1.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=18" + "node": ">=10" } }, - "node_modules/fluent-ffmpeg/node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" - }, - "node_modules/fluent-ffmpeg/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=8" } }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "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", + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "fetch-blob": "^3.1.2" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/forwarded-parse": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", - "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", - "license": "MIT" - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "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": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "@isaacs/cliui": "^8.0.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "url": "https://github.com/sponsors/isaacs" }, - "engines": { - "node": ">= 0.4" + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "peer": true, "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": "18 || 20 || >=22" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "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==", + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.3" + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">=10.13.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/globals": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", - "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=18" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" + "node_modules/jest-config/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/groups": { - "resolved": "services/groups", - "link": true + "node_modules/jest-config/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/h264-profile-level-id": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/h264-profile-level-id/-/h264-profile-level-id-2.3.2.tgz", - "integrity": "sha512-hnq1UDlw7WGJV6GCr/g7wnkHYUjdAY2bis9rgn2JqSdQS2WfVvnt1ZE9g8nTguracodf5LLKZOwURsDN49YtBQ==", + "node_modules/jest-config/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": { - "debug": "^4.4.3" + "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": ">=20" + "node": "*" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mediasoup" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "license": "MIT", + "node_modules/jest-config/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": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": "*" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-config/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "license": "MIT", - "bin": { - "he": "bin/he" + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", - "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, "license": "MIT", "dependencies": { - "deep-equal": "~1.0.1", - "http-errors": "~1.8.0" + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">= 0.8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-assert/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-assert/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, "license": "MIT", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/http-assert/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, "license": "MIT", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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": "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==", + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-in-the-middle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.0.tgz", - "integrity": "sha512-OnGy+eYT7wVejH2XWgLRgbmzujhhVIATQH0ztIeRilwHBjTeG3pD+XnH3PKX0r9gJ0BuJmJ68q/oh9qgXnNDQg==", - "license": "Apache-2.0", "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=18" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "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": ">=0.8.19" + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/ioredis": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.3.tgz", - "integrity": "sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==", + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, "license": "MIT", "dependencies": { - "@ioredis/commands": "1.5.0", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=12.22.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ipaddr.js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", - "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, "engines": { - "node": ">= 10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "node_modules/jest-runtime/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/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jest-runtime/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/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": ">=0.10.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-runtime/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": "MIT", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, "engines": { - "node": ">=0.12.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "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==", + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, "node_modules/jose": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", @@ -4329,6 +8124,13 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", @@ -4361,6 +8163,13 @@ "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", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-ref-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", @@ -4394,29 +8203,17 @@ "dev": true, "license": "MIT" }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", "bin": { - "JSONStream": "bin.js" + "json5": "lib/cli.js" }, "engines": { - "node": "*" + "node": ">=6" } }, "node_modules/jsonwebtoken": { @@ -4493,6 +8290,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/koa": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/koa/-/koa-3.1.2.tgz", @@ -4577,6 +8384,16 @@ "node": ">= 0.6" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4648,9 +8465,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.defaults": { @@ -4701,6 +8518,13 @@ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "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.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -4708,24 +8532,22 @@ "license": "MIT" }, "node_modules/long": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.5.tgz", - "integrity": "sha512-e0r9YBBgNCq1D1o5Dp8FMH0N5hsFtXDBiVa0qoJPHpakvZkmDKPRoGffZJII/XsHvj9An9blm+cRJ01yQqU+Dw==", + "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": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "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": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4741,10 +8563,65 @@ "node": ">=12" } }, + "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/main": { "resolved": "services/main", "link": true }, + "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/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "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/marketplace": { "resolved": "services/marketplace", "link": true @@ -4807,10 +8684,18 @@ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "license": "MIT" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "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", @@ -4841,6 +8726,16 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -4854,12 +8749,12 @@ } }, "node_modules/minimatch": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -4971,6 +8866,39 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/mocha/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/mocha/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/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/module-alias": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.3.4.tgz", @@ -5109,9 +9037,9 @@ "license": "MIT" }, "node_modules/msgpackr": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.5.tgz", - "integrity": "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==", + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.12.tgz", + "integrity": "sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==", "license": "MIT", "optionalDependencies": { "msgpackr-extract": "^3.0.2" @@ -5155,9 +9083,9 @@ } }, "node_modules/nanoid": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", - "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz", + "integrity": "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==", "funding": [ { "type": "github", @@ -5243,9 +9171,9 @@ "license": "MIT" }, "node_modules/node-addon-api": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", - "integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", "license": "MIT", "engines": { "node": "^18 || ^20 || >= 21" @@ -5315,19 +9243,56 @@ "node-gyp-build-optional-packages-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-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, "node_modules/nodemailer": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", - "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.5.tgz", + "integrity": "sha512-0PF8Yb1yZuQfQbq+5/pZJrtF6WQcjTd5/S4JOHs9PGFxuTqoB/icwuB44pOdURHJbRKX1PPoJZtY7R4VUoCC8w==", "license": "MIT-0", "engines": { - "node": ">=6.0.0" + "node": ">=6.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/notifications": { + "resolved": "services/notifications", + "link": true + }, + "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/notifications": { - "resolved": "services/notifications", - "link": true - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5337,15 +9302,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.1.4.tgz", - "integrity": "sha512-W6muQbHEfHqZusW/fNQT+Z1WAE0FgjfxtGOdSpOfWYVHYBuPu/geEwikhGftiwJwQ7waei/kB2kY4SD70bTR6A==", - "license": "MIT", - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -5400,6 +9356,22 @@ "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", @@ -5465,6 +9437,42 @@ "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", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -5485,9 +9493,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", - "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -5499,6 +9507,16 @@ "node": ">=14.0.0" } }, + "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", @@ -5508,6 +9526,13 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, "node_modules/path-scurry": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", @@ -5526,22 +9551,30 @@ } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, + "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": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "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": "*" + "node": ">= 14.16" } }, "node_modules/pg-int8": { @@ -5583,9 +9616,10 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "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" @@ -5603,6 +9637,123 @@ "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "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": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", @@ -5717,17 +9868,56 @@ "node": ">= 0.8.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.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/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/pump": { "version": "3.0.3", @@ -5748,6 +9938,23 @@ "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "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.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", @@ -5841,6 +10048,13 @@ "node": ">=0.10.0" } }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -5855,59 +10069,6 @@ "node": ">= 6" } }, - "node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/readdirp/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp/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/readdirp/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", @@ -5929,12 +10090,6 @@ "node": ">=4" } }, - "node_modules/regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", - "license": "MIT" - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5964,7 +10119,61 @@ "module-details-from-path": "^1.0.3" }, "engines": { - "node": ">=9.3.0 || >=8.10.0 <9.0.0" + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "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" + } + }, + "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", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" } }, "node_modules/rfdc": { @@ -5973,6 +10182,51 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, + "node_modules/rollup": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.0.tgz", + "integrity": "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.0", + "@rollup/rollup-android-arm64": "4.60.0", + "@rollup/rollup-darwin-arm64": "4.60.0", + "@rollup/rollup-darwin-x64": "4.60.0", + "@rollup/rollup-freebsd-arm64": "4.60.0", + "@rollup/rollup-freebsd-x64": "4.60.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.0", + "@rollup/rollup-linux-arm-musleabihf": "4.60.0", + "@rollup/rollup-linux-arm64-gnu": "4.60.0", + "@rollup/rollup-linux-arm64-musl": "4.60.0", + "@rollup/rollup-linux-loong64-gnu": "4.60.0", + "@rollup/rollup-linux-loong64-musl": "4.60.0", + "@rollup/rollup-linux-ppc64-gnu": "4.60.0", + "@rollup/rollup-linux-ppc64-musl": "4.60.0", + "@rollup/rollup-linux-riscv64-gnu": "4.60.0", + "@rollup/rollup-linux-riscv64-musl": "4.60.0", + "@rollup/rollup-linux-s390x-gnu": "4.60.0", + "@rollup/rollup-linux-x64-gnu": "4.60.0", + "@rollup/rollup-linux-x64-musl": "4.60.0", + "@rollup/rollup-openbsd-x64": "4.60.0", + "@rollup/rollup-openharmony-arm64": "4.60.0", + "@rollup/rollup-win32-arm64-msvc": "4.60.0", + "@rollup/rollup-win32-ia32-msvc": "4.60.0", + "@rollup/rollup-win32-x64-gnu": "4.60.0", + "@rollup/rollup-win32-x64-msvc": "4.60.0", + "fsevents": "~2.3.2" + } + }, "node_modules/rtc": { "resolved": "services/rtc", "link": true @@ -6039,9 +10293,9 @@ } }, "node_modules/serialize-javascript": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.4.tgz", - "integrity": "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6182,6 +10436,20 @@ "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", "license": "MIT" }, + "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": "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/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -6267,6 +10535,23 @@ "node": ">=8" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/snowflake-uuid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/snowflake-uuid/-/snowflake-uuid-1.0.0.tgz", @@ -6285,6 +10570,27 @@ "node": ">=0.10.0" } }, + "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": { + "node": ">=0.10.0" + } + }, + "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/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -6303,6 +10609,43 @@ "node": ">=6" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "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", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/standard-as-callback": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", @@ -6318,6 +10661,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/stream-chain": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", @@ -6370,6 +10720,20 @@ "safe-buffer": "~5.2.0" } }, + "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": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -6385,6 +10749,22 @@ "node": ">=8" } }, + "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/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -6398,6 +10778,40 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "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" + }, + "engines": { + "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": "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/strip-json-comments": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", @@ -6411,10 +10825,30 @@ "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/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "funding": [ { "type": "github", @@ -6477,6 +10911,19 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tar": { "version": "7.5.11", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", @@ -6494,9 +10941,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", - "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", + "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", "license": "MIT", "dependencies": { "pump": "^3.0.0", @@ -6508,12 +10955,13 @@ } }, "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", + "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } @@ -6523,11 +10971,78 @@ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "license": "MIT", - "optional": true, "dependencies": { "streamx": "^2.12.5" } }, + "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.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "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-decoder": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", @@ -6558,12 +11073,6 @@ "node": ">=0.8" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, "node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", @@ -6573,6 +11082,20 @@ "readable-stream": "3" } }, + "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" + }, + "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/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -6607,9 +11130,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "peer": true, "engines": { @@ -6619,10 +11142,48 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -6666,29 +11227,95 @@ "dependencies": { "punycode": "^2.3.1" }, - "engines": { - "node": ">=18" + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "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 <6" + }, + "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-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "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", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=18.12" + "node": ">=16" }, - "peerDependencies": { - "typescript": ">=4.8.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -6739,11 +11366,25 @@ "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.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/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -6807,9 +11448,9 @@ } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "license": "MIT" }, "node_modules/universal-user-agent": { @@ -6827,6 +11468,37 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "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", @@ -6847,24 +11519,26 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/uWebSockets.js": { "version": "20.57.0", "resolved": "git+ssh://git@github.com/uNetworking/uWebSockets.js.git#fcfc622a4286909593b7f390056d89e0ca3b56b9", "license": "Apache-2.0" }, + "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/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6874,6 +11548,251 @@ "node": ">= 0.8" } }, + "node_modules/vite": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.27.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/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/vite/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "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.4", + "@vitest/ui": "3.2.4", + "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/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/vitest/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -6920,6 +11839,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/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -6961,12 +11897,45 @@ "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/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/xml2js": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", @@ -6998,6 +11967,19 @@ "node": ">=0.4" } }, + "node_modules/xxhash-addon": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/xxhash-addon/-/xxhash-addon-2.1.0.tgz", + "integrity": "sha512-y69Lhs6msXn4eLPZkDqSKff3OLHyOL7a5lhxbJ0NN4x6XYhVI+lKIXt7JxQqSHssEhUWLgAWIbUbT9X9KUTbcw==", + "hasInstallScript": true, + "license": "BSD-2-Clause", + "dependencies": { + "node-gyp-build": "^4.8.0" + }, + "engines": { + "node": ">=8.6.0 <9.0.0 || >=10.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -7087,8 +12069,8 @@ }, "services/ems": { "dependencies": { - "handlebars": "^4.7.8", - "nodemailer": "^7.0.10" + "handlebars": "^4.7.9", + "nodemailer": "^8.0.5" } }, "services/files": { @@ -7097,7 +12079,8 @@ "fluent-ffmpeg": "^2.1.2", "mime-types": "^2.1.35", "p-map": "4", - "sharp": "0.32.6" + "sharp": "0.32.6", + "xxhash-addon": "^2.1.0" } }, "services/groups": {}, diff --git a/packages/server/package.json b/packages/server/package.json index 3fcb64c21..fad735134 100755 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -2,6 +2,7 @@ "name": "@comty/server", "version": "2.14.0@alpha", "license": "ComtyLicense", + "type": "module", "private": true, "workspaces": [ "services/*" @@ -11,39 +12,41 @@ "start:prod": "cross-env NODE_ENV=production ultragateway", "dev": "cross-env NODE_ENV=development DEBUG=true ultragateway", "dev:exp": "cross-env NODE_ENV=development ../../linebridge/linebridge-gateway/debug", - "preinstall": "bash ./scripts/externalDeps.sh" + "preinstall": "bash ./scripts/externalDeps.sh", + "test": "vitest run", + "test:watch": "vitest", + "test:coverage": "vitest run --coverage" }, "dependencies": { + "@foxify/events": "^2.1.0", + "@ragestudio/scylla-odm": "^0.21.0", "@sentry/node": "^10.44.0", - "axios": "^1.13.6", + "@types/luxon": "^3.7.1", + "axios": "^1.16.0", "bcrypt": "^6.0.0", "bullmq": "^5.71.0", - "cassandra-driver": "^4.8.0", "cross-env": "^10.1.0", - "express-cassandra": "^2.9.1", "jsonwebtoken": "^9.0.3", "jws": "^4.0.1", "linebridge": "^1.8.1", + "lodash": "^4.18.1", "minio": "^8.0.7", "mongoose": "^9.3.1", "qs": "^6.15.0" }, "devDependencies": { "@eslint/js": "^10.0.1", + "@types/jest": "^29.5.0", "@typescript-eslint/eslint-plugin": "^8.57.1", + "@vitest/coverage-v8": "^3.0.9", "chai": "^6.2.2", "eslint": "^10.0.3", "globals": "^17.4.0", + "jest": "^29.5.0", "mocha": "^12.0.0-beta.9", - "sinon": "^21.0.3" - }, - "overrides": { - "braces": "3.0.3", - "minimatch": "10.2.3", - "fast-xml-parser": "5.5.6", - "diff": "8.0.3", - "micromatch": "4.0.8", - "string-width": "4.2.3" + "sinon": "^21.0.3", + "ts-jest": "^29.1.0", + "vitest": "^3.0.9" }, "optionalDependencies": { "bufferutil": "^4.1.0" diff --git a/packages/server/scylla_db_models/auth_session.js b/packages/server/scylla_db_models/auth_session.js deleted file mode 100644 index d70299c55..000000000 --- a/packages/server/scylla_db_models/auth_session.js +++ /dev/null @@ -1,14 +0,0 @@ -export default { - key: [["_id"], "user_id"], - table_name: "auth_sessions", - fields: { - _id: "varchar", - token: "varchar", - user_id: "varchar", - username: "varchar", - sign_location: "varchar", - ip_address: "varchar", - client: "varchar", - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/channel_messages.js b/packages/server/scylla_db_models/channel_messages.js deleted file mode 100644 index 60e3be0f8..000000000 --- a/packages/server/scylla_db_models/channel_messages.js +++ /dev/null @@ -1,23 +0,0 @@ -export default { - key: [["channel_id"], "_id"], - clustering_order: { _id: "asc" }, - table_name: "channel_messages", - fields: { - _id: "varchar", - channel_id: "varchar", - user_id: "varchar", - message: "varchar", - attachments: { - type: "frozen", - typeDef: ">>", - }, - flags: { - type: "frozen", - typeDef: ">", - }, - sticker: "varchar", - reply_to_id: "varchar", - updated_at: "timestamp", - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/channel_messages_ack.js b/packages/server/scylla_db_models/channel_messages_ack.js deleted file mode 100644 index 39e801410..000000000 --- a/packages/server/scylla_db_models/channel_messages_ack.js +++ /dev/null @@ -1,10 +0,0 @@ -export default { - key: [["message_id"], "_id"], - table_name: "channel_messages_ack", - fields: { - _id: "varchar", - message_id: "varchar", - user_id: "varchar", - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/channel_orders.js b/packages/server/scylla_db_models/channel_orders.js deleted file mode 100644 index 7596451e7..000000000 --- a/packages/server/scylla_db_models/channel_orders.js +++ /dev/null @@ -1,11 +0,0 @@ -export default { - key: ["group_id"], - table_name: "group_channels_order", - fields: { - group_id: "varchar", - order: { - type: "list", - typeDef: "", - }, - }, -} diff --git a/packages/server/scylla_db_models/direct_messages_activity.js b/packages/server/scylla_db_models/direct_messages_activity.js deleted file mode 100644 index bf19cd378..000000000 --- a/packages/server/scylla_db_models/direct_messages_activity.js +++ /dev/null @@ -1,12 +0,0 @@ -export default { - key: [["user_id"], "room_id"], - table_name: "direct_messages_activity", - fields: { - user_id: "varchar", - room_id: "varchar", - to_user_id: "varchar", - last_message_at: "timestamp", - direction: "text", - short_message: "text", - }, -} diff --git a/packages/server/scylla_db_models/direct_messages_rooms.js b/packages/server/scylla_db_models/direct_messages_rooms.js deleted file mode 100644 index 404bd84bb..000000000 --- a/packages/server/scylla_db_models/direct_messages_rooms.js +++ /dev/null @@ -1,10 +0,0 @@ -export default { - key: [["pair_key"], "_id"], - table_name: "direct_messages_rooms", - fields: { - _id: "varchar", - pair_key: "varchar", - name: "varchar", - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/group_channels.js b/packages/server/scylla_db_models/group_channels.js deleted file mode 100644 index 48a616ff5..000000000 --- a/packages/server/scylla_db_models/group_channels.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - key: [["group_id"], "_id"], - table_name: "group_channels", - fields: { - _id: "varchar", - group_id: "varchar", - kind: "varchar", - name: "varchar", - description: "varchar", - explicit: "boolean", - params: { - type: "map", - typeDef: "", - }, - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/group_invite_key.js b/packages/server/scylla_db_models/group_invite_key.js deleted file mode 100644 index 05a8e04ce..000000000 --- a/packages/server/scylla_db_models/group_invite_key.js +++ /dev/null @@ -1,16 +0,0 @@ -export default { - key: [["group_id"], "key"], - table_name: "groups_invite_keys", - fields: { - group_id: "varchar", - key: "varchar", - issuer_user_id: "varchar", - created_at: "timestamp", - expires_at: "timestamp", - max_usage: "int", - usages: { - type: "int", - default: 0, - }, - }, -} diff --git a/packages/server/scylla_db_models/group_memberships.js b/packages/server/scylla_db_models/group_memberships.js deleted file mode 100644 index 107cf193f..000000000 --- a/packages/server/scylla_db_models/group_memberships.js +++ /dev/null @@ -1,14 +0,0 @@ -export default { - key: [["user_id"], "group_id", "_id"], - table_name: "group_memberships", - fields: { - _id: "varchar", - group_id: "varchar", - user_id: "varchar", - roles: { - type: "frozen", - typeDef: ">", - }, - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/group_roles.js b/packages/server/scylla_db_models/group_roles.js deleted file mode 100644 index e4822493a..000000000 --- a/packages/server/scylla_db_models/group_roles.js +++ /dev/null @@ -1,12 +0,0 @@ -export default { - key: [["group_id"], "role_key"], - table_name: "group_roles", - fields: { - group_id: "varchar", - role_key: "varchar", - permissions: { - type: "frozen", - typeDef: ">>", - }, - }, -} diff --git a/packages/server/scylla_db_models/groups.js b/packages/server/scylla_db_models/groups.js deleted file mode 100644 index 60033fe3a..000000000 --- a/packages/server/scylla_db_models/groups.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - key: ["_id"], - table_name: "groups", - fields: { - _id: "varchar", - name: "varchar", - description: "varchar", - icon: "varchar", - cover: "varchar", - reachability: { - type: "varchar", - default: "private", - }, - owner_user_id: "varchar", - created_at: "timestamp", - }, -} diff --git a/packages/server/scylla_db_models/groups_user_orders.js b/packages/server/scylla_db_models/groups_user_orders.js deleted file mode 100644 index b4f51d884..000000000 --- a/packages/server/scylla_db_models/groups_user_orders.js +++ /dev/null @@ -1,11 +0,0 @@ -export default { - key: ["user_id"], - table_name: "groups_user_orders", - fields: { - user_id: "varchar", - order: { - type: "list", - typeDef: "", - }, - }, -} diff --git a/packages/server/scylla_db_models/oidc_apps.js b/packages/server/scylla_db_models/oidc_apps.js deleted file mode 100644 index f00b84f30..000000000 --- a/packages/server/scylla_db_models/oidc_apps.js +++ /dev/null @@ -1,22 +0,0 @@ -export default { - key: ["client_id"], - table_name: "oidc_apps", - fields: { - client_id: "text", - client_secret: "text", - owner_id: "uuid", - client_name: "text", - redirect_uris: { - type: "list", - typeDef: "", - }, - grant_types: { - type: "list", - typeDef: "", - }, - response_types: { - type: "list", - typeDef: "", - }, - }, -} diff --git a/packages/server/scylla_db_models/oidc_store.js b/packages/server/scylla_db_models/oidc_store.js deleted file mode 100644 index 281ebd9b8..000000000 --- a/packages/server/scylla_db_models/oidc_store.js +++ /dev/null @@ -1,13 +0,0 @@ -export default { - key: ["id"], - indexes: ["grantId", "uid"], - table_name: "oidc_store", - fields: { - id: "text", - type: "text", - payload: "text", - grantId: "text", - uid: "text", - consumedAt: "timestamp", - }, -} diff --git a/packages/server/services/auth/auth.service.js b/packages/server/services/auth/auth.service.js index edbce74fe..5b696db4c 100644 --- a/packages/server/services/auth/auth.service.js +++ b/packages/server/services/auth/auth.service.js @@ -1,7 +1,7 @@ import { Server } from "linebridge" import crypto from "node:crypto" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import TaskQueueManager from "@shared-classes/TaskQueueManager" diff --git a/packages/server/services/auth/classes/oicd/index.js b/packages/server/services/auth/classes/oicd/index.js index a777c12e5..4cc09f541 100644 --- a/packages/server/services/auth/classes/oicd/index.js +++ b/packages/server/services/auth/classes/oicd/index.js @@ -26,7 +26,7 @@ class Adapter { response_types: payload.response_types || [], }) - return await client.saveAsync() + return await client.save() } const options = expiresIn ? { ttl: expiresIn } : {} @@ -39,12 +39,12 @@ class Adapter { uid: payload.uid, }) - await store.saveAsync(options) + await store.save(options) } async find(id) { if (this.name === "Client") { - const client = await Adapter.OidcClient.findOneAsync( + const client = await Adapter.OidcClient.findOne( { client_id: id }, { raw: true }, ) @@ -59,28 +59,25 @@ class Adapter { } } - const data = await Adapter.OidcStore.findOneAsync( - { id: id }, - { raw: true }, - ) + const data = await Adapter.OidcStore.findOne({ id: id }, { raw: true }) return data ? JSON.parse(data.payload) : undefined } async consume(id) { - const data = await Adapter.OidcStore.findOneAsync({ id: id }) + const data = await Adapter.OidcStore.findOne({ id: id }) if (data) { data.consumedAt = new Date() - await data.saveAsync() + await data.save() } } async destroy(id) { - await Adapter.OidcStore.deleteAsync({ id: id }) + await Adapter.OidcStore.delete({ id: id }) } async revokeByGrantId(grantId) { - await Adapter.OidcStore.deleteAsync({ grantId: grantId }) + await Adapter.OidcStore.delete({ grantId: grantId }) } } @@ -148,13 +145,13 @@ export default class OIDCProvider { response_types: ["code"], }) - await newApp.saveAsync() + await newApp.save() return { clientId, clientSecret } } async getAppsByDeveloper(userId) { - return await Adapter.OidcClient.findAsync( + return await Adapter.OidcClient.find( { owner_id: userId }, { raw: true }, ) diff --git a/packages/server/services/auth/classes/session/create.js b/packages/server/services/auth/classes/session/create.js index af5a13ca4..bad0f8983 100644 --- a/packages/server/services/auth/classes/session/create.js +++ b/packages/server/services/auth/classes/session/create.js @@ -1,17 +1,18 @@ import AuthToken from "@shared-classes/AuthToken" +import SessionModel from "@db/auth_session" export default async function (payload) { // generate a new session id const session_id = nanoid() // create a new Session obj - const session = new this.Model({ + const session = SessionModel.obj({ _id: session_id, user_id: payload.user_id, sign_location: payload.sign_location, ip_address: payload.ip_address, client: payload.client, - created_at: new Date().getTime(), + created_at: new Date(), }) // create and sign a new auth token @@ -35,10 +36,10 @@ export default async function (payload) { session.token = signedAuthToken // save the session - await session.saveAsync() + await session.save() return { - data: session.toJSON(), + data: session.toRaw(), authToken: signedAuthToken, refreshToken: signedRefreshToken, expiresIn: AuthToken.authStrategy.expiresIn, diff --git a/packages/server/services/auth/classes/session/delete.js b/packages/server/services/auth/classes/session/delete.js index 40816ff2a..e358a116d 100644 --- a/packages/server/services/auth/classes/session/delete.js +++ b/packages/server/services/auth/classes/session/delete.js @@ -1,13 +1,20 @@ -export default async function (session_id) { - const session = await this.Model.findOneAsync({ +import SessionModel from "@db/auth_session" + +export default async function (session_id, user_id) { + if (!session_id || !user_id) { + throw new OperationError(400, "Session ID and user ID are required") + } + + const session = await SessionModel.findOne({ _id: session_id, + user_id: user_id, }) if (!session) { throw new OperationError(401, "Session not found or not valid") } - await session.deleteAsync() + await session.delete() - return session.toJSON() + return session.toRaw() } diff --git a/packages/server/services/auth/classes/session/deleteAllByUserId.js b/packages/server/services/auth/classes/session/deleteAllByUserId.js index ae1d2d21b..921185df7 100644 --- a/packages/server/services/auth/classes/session/deleteAllByUserId.js +++ b/packages/server/services/auth/classes/session/deleteAllByUserId.js @@ -1,5 +1,11 @@ +import SessionModel from "@db/auth_session" + export default async function (user_id) { - const sessions = await this.Model.findAsync( + if (!user_id) { + throw new OperationError(400, "User ID is required") + } + + const sessions = await SessionModel.find( { user_id: user_id, }, @@ -9,7 +15,7 @@ export default async function (user_id) { ) for await (const session of sessions) { - await session.deleteAsync() + await session.delete() } return sessions.length diff --git a/packages/server/services/auth/classes/session/get.js b/packages/server/services/auth/classes/session/get.js index 73ab7cc7a..9e06ab466 100644 --- a/packages/server/services/auth/classes/session/get.js +++ b/packages/server/services/auth/classes/session/get.js @@ -1,5 +1,7 @@ +import SessionModel from "@db/auth_session" + export default async function (session_id) { - return await this.Model.findOneAsync( + return await SessionModel.findOne( { _id: session_id, }, diff --git a/packages/server/services/auth/classes/session/getAllByUserId.js b/packages/server/services/auth/classes/session/getAllByUserId.js index 777dfd217..fe583f108 100644 --- a/packages/server/services/auth/classes/session/getAllByUserId.js +++ b/packages/server/services/auth/classes/session/getAllByUserId.js @@ -1,5 +1,7 @@ +import SessionModel from "@db/auth_session" + export default async function (user_id) { - return await this.Model.findAsync( + return await SessionModel.find( { user_id: user_id, }, diff --git a/packages/server/services/auth/classes/session/handleRefresh.js b/packages/server/services/auth/classes/session/handleRefresh.js index 70367eb8f..41ddef9c5 100644 --- a/packages/server/services/auth/classes/session/handleRefresh.js +++ b/packages/server/services/auth/classes/session/handleRefresh.js @@ -1,4 +1,5 @@ import AuthToken from "@shared-classes/AuthToken" +import SessionModel from "@db/auth_session" export default async function (req) { if (!req.body.refreshToken || !req.body.authToken) { @@ -15,13 +16,10 @@ export default async function (req) { throw new OperationError(401, "Invalid refresh token format") } - let session = await this.Model.findOneAsync( - { - _id: validation.data.session_id, - user_id: validation.data.user_id, - }, - { raw: true }, - ) + let session = await SessionModel.findOne({ + _id: validation.data.session_id, + user_id: validation.data.user_id, + }) // check if session not found if (!session) { @@ -39,7 +37,7 @@ export default async function (req) { const newAuthToken = await AuthToken.signToken( { ...validation.data, - session_id: session._id.toString(), + session_id: session._id, }, "authStrategy", ) @@ -50,15 +48,9 @@ export default async function (req) { ) // update session token - await this.Model.updateAsync( - { - _id: session._id.toString(), - user_id: session.user_id, - }, - { - token: newAuthToken, - }, - ) + session.token = newAuthToken + + await session.save() return { token: newAuthToken, diff --git a/packages/server/services/auth/classes/session/index.js b/packages/server/services/auth/classes/session/index.js index a976a072a..c96ce6dcc 100644 --- a/packages/server/services/auth/classes/session/index.js +++ b/packages/server/services/auth/classes/session/index.js @@ -8,10 +8,6 @@ import deleteAllByUserIdMethod from "./deleteAllByUserId" import handleRefreshMethod from "./handleRefresh" export default class Session { - static get Model() { - return global.scylla.model("auth_session") - } - static get = getMethod.bind(this) static create = createMethod.bind(this) static delete = deleteMethod.bind(this) diff --git a/packages/server/services/auth/routes/auth/delete.js b/packages/server/services/auth/routes/auth/delete.js index 9ef6b1663..17908d363 100644 --- a/packages/server/services/auth/routes/auth/delete.js +++ b/packages/server/services/auth/routes/auth/delete.js @@ -3,6 +3,6 @@ import Session from "@classes/session" export default { useMiddlewares: ["withAuthentication"], fn: async (req) => { - return await Session.delete(req.auth.session._id) + return await Session.delete(req.auth.session._id, req.auth.user_id) }, } diff --git a/packages/server/services/chats/chats.service.js b/packages/server/services/chats/chats.service.js index f1dc53690..29adf823d 100755 --- a/packages/server/services/chats/chats.service.js +++ b/packages/server/services/chats/chats.service.js @@ -3,8 +3,7 @@ import { Worker as SnowflakeWorker } from "snowflake-uuid" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" -import InjectedAuth from "@shared-lib/injectedAuth" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import SharedMiddlewares from "@shared-middlewares" @@ -30,7 +29,9 @@ class API extends Server { contexts = { db: new DbManager(), - scylla: (global.scylla = new ScyllaDb()), + scylla: (global.scylla = new ScyllaDb({ + modelsPath: global["paths"].root + "/db", + })), redis: RedisClient(), groupChannels: new GroupChatChannelController(this), dmChannels: new DMChatChannelController(this), @@ -45,7 +46,9 @@ class API extends Server { await this.contexts.db.initialize() await this.contexts.redis.initialize() - await this.contexts.scylla.initialize() + await this.contexts.scylla.initialize({ + sync: true, + }) } } diff --git a/packages/server/services/chats/classes/ChatChannel/delete.js b/packages/server/services/chats/classes/ChatChannel/delete.js deleted file mode 100644 index b63156ef1..000000000 --- a/packages/server/services/chats/classes/ChatChannel/delete.js +++ /dev/null @@ -1,35 +0,0 @@ -export default async function (user, messageId) { - if (!user) { - throw new OperationError(400, "Missing user object") - } - - if (typeof messageId !== "string") { - throw new OperationError(400, "Missing messageId") - } - - const Message = this.scylla.model("channel_messages") - - // try to fetch the message - const message = await Message.findOneAsync({ - channel_id: this.channel._id.toString(), - _id: messageId, - }) - - if (!message) { - throw new OperationError(404, "Message not found") - } - - // check if is the owner of the message - // TODO: use permissions api - if (message.user_id !== user._id.toString()) { - throw new OperationError(403, "You are not the owner of this message") - } - - await message.deleteAsync() - - this.sendEventToChannelTopic("channel:message:deleted", { - _id: message._id.toString(), - }) - - return message -} diff --git a/packages/server/services/chats/classes/ChatChannel/delete.ts b/packages/server/services/chats/classes/ChatChannel/delete.ts new file mode 100644 index 000000000..0975aca49 --- /dev/null +++ b/packages/server/services/chats/classes/ChatChannel/delete.ts @@ -0,0 +1,77 @@ +import ChatChannel from "." + +import MessageModel from "@db/channel_messages" +import DeletedMessageModel from "@db/channel_deleted_messages" +import ChannelLogModel from "@db/channel_log" + +export default async function ( + this: ChatChannel, + user: any, + messageId: string, +) { + if (!user) { + throw new OperationError(400, "Missing user object") + } + + if (typeof messageId !== "string") { + throw new OperationError(400, "Missing messageId") + } + + // try to fetch the message + const message = await MessageModel.findOne({ + channel_id: this.channel._id.toString(), + _id: messageId, + }) + + if (!message) { + throw new OperationError(404, "Message not found") + } + + // check if is the owner of the message + // TODO: use permissions api + if (message.user_id !== user._id.toString()) { + throw new OperationError(403, "You are not the owner of this message") + } + + // create batch + const batch = this.scylla.batch() + + // delete message + MessageModel.batch.delete(batch, message.toRaw()) + + ChannelLogModel.batch.insert(batch, { + channel_id: this.channel._id.toString(), + log_id: this.snowflake.nextId().toString(), + type: "message:deleted", + target_id: message._id, + actor_id: user._id, + timestamp: new Date(), + }) + + // // create a new deleted message obj + // DeletedMessageModel.batch.insert(batch, { + // _id: messageId, + // channel_id: this.channel._id.toString(), + // deleted_by_user_id: user._id.toString(), + // deleted_at: new Date(), + // }) + + // if onDelete callback is defined, execute it + if (typeof this.onDelete === "function") { + try { + await this.onDelete(user, message, batch) + } catch (error) { + console.error("Failed to execute onDelete hook", error) + throw error + } + } + + // execute the batch + await batch.execute() + + this.sendEventToChannelTopic("channel:message:deleted", { + _id: message._id.toString(), + }) + + return message +} diff --git a/packages/server/services/chats/classes/ChatChannel/index.js b/packages/server/services/chats/classes/ChatChannel/index.js deleted file mode 100644 index fad212eb1..000000000 --- a/packages/server/services/chats/classes/ChatChannel/index.js +++ /dev/null @@ -1,76 +0,0 @@ -import readMethod from "./read" -import writeMethod from "./write" -import updateMethod from "./update" -import deleteMethod from "./delete" - -export default class ChatChannel { - constructor( - controller, - channel, - { onWrite, onRead, topic = "chats:channel" } = {}, - ) { - this.controller = controller - this.channel = channel - - this.scylla = controller.server.contexts.scylla - this.snowflake = controller.server.contexts.snowflake - - this.onWrite = onWrite - this.onRead = onRead - this.topic = topic - } - - get MessageModel() { - return this.scylla.model("channel_messages") - } - - get _id() { - return this.channel._id - } - - static defaultLimits = { - maxMessageLength: 1200, - maxAttachments: 10, - } - - read = readMethod.bind(this) - write = writeMethod.bind(this) - delete = deleteMethod.bind(this) - update = updateMethod.bind(this) - - validateMessagePayload = (payload) => { - if (!payload.message && !payload.attachments && !payload.sticker) { - throw new OperationError( - 400, - "Missing message or attachments or sticker", - ) - } - - if (payload.message) { - if ( - payload.message.length > - ChatChannel.defaultLimits.maxMessageLength - ) { - throw new OperationError(400, "Message is too long") - } - } - - if (payload.attachments) { - if ( - payload.attachments && - payload.attachments?.length > - ChatChannel.defaultLimits.maxAttachments - ) { - throw new OperationError(400, "Too many attachments") - } - } - } - - async sendEventToChannelTopic(event, data) { - return this.controller.server.engine.ws.senders.toTopic( - `${this.topic}:${this.channel._id.toString()}`, - event, - data, - ) - } -} diff --git a/packages/server/services/chats/classes/ChatChannel/index.ts b/packages/server/services/chats/classes/ChatChannel/index.ts new file mode 100644 index 000000000..2c6ff2a32 --- /dev/null +++ b/packages/server/services/chats/classes/ChatChannel/index.ts @@ -0,0 +1,152 @@ +import type { Worker as SnowflakeWorker } from "snowflake-uuid" +import type ScyllaClientType from "@ragestudio/scylla-odm" +import { Doc, InferDoc } from "@ragestudio/scylla-odm/types" + +import readMethod from "./read" +import writeMethod from "./write" +import updateMethod from "./update" +import deleteMethod from "./delete" + +import ChannelMessagesModel from "@db/channel_messages" +import { Batch } from "@ragestudio/scylla-odm" + +export type onWriteCallbackType = ( + user: RTEClient, + message: Doc>, + batch: Batch, +) => Promise +export type onReadCallbackType = ( + user: RTEClient, + messages: Doc>[], + users: any[], + batch: Batch, +) => Promise +export type onDeleteCallbackType = ( + user: RTEClient, + message: Doc>, + batch: Batch, +) => Promise + +export type ChatChannelOptions = { + onWrite?: onWriteCallbackType + onRead?: onReadCallbackType + onDelete?: onDeleteCallbackType + topic?: string +} + +export default class ChatChannel { + constructor(controller: any, channel: any, options?: ChatChannelOptions) { + this.controller = controller + this.channel = channel + this.topic = options?.topic ?? "chats:channel" + + this.scylla = controller.server.contexts.scylla + this.snowflake = controller.server.contexts.snowflake + + if (typeof options?.onWrite === "function") { + this.onWrite = options.onWrite + } + if (typeof options?.onRead === "function") { + this.onRead = options.onRead + } + if (typeof options?.onDelete === "function") { + this.onDelete = options.onDelete + } + } + + topic: string + scylla: ScyllaClientType + snowflake: SnowflakeWorker + controller: any + channel: any + + onWrite: onWriteCallbackType + onRead: onReadCallbackType + onDelete: onDeleteCallbackType + + get _id() { + return this.channel._id + } + + static defaultLimits = { + maxMessageLength: 1200, + maxAttachments: 10, + } + + read = readMethod.bind(this) + write = writeMethod.bind(this) + delete = deleteMethod.bind(this) + update = updateMethod.bind(this) + + validateMessagePayload = (payload: any) => { + if (!payload.message && !payload.attachments && !payload.sticker) { + throw new OperationError( + 400, + "Missing message or attachments or sticker", + ) + } + + if (payload.message) { + if ( + payload.message.length > + ChatChannel.defaultLimits.maxMessageLength + ) { + throw new OperationError(400, "Message is too long") + } + } + + if (payload.attachments) { + if ( + payload.attachments && + payload.attachments?.length > + ChatChannel.defaultLimits.maxAttachments + ) { + throw new OperationError(400, "Too many attachments") + } + } + } + + async getLastMessageObj() { + const message = await ChannelMessagesModel.find( + { + channel_id: this._id, + }, + { + limit: 1, + orderBy: { + _id: "desc", + }, + }, + ) + + if (message.length === 0) { + throw new OperationError(404, "No last message found") + } + + return message[0] + } + + async getFirstMessageBeforeId(messageId: string) { + return await ChannelMessagesModel.findOne( + { + channel_id: this._id, + _id: { + $lt: messageId, + }, + }, + { + orderBy: { + _id: "desc", + }, + }, + ) + } + + async sendEventToChannelTopic(event: string, data: any) { + return this.controller.server.engine.ws.senders.toTopic( + `${this.topic}:${this.channel._id.toString()}`, + event, + data, + ) + } +} diff --git a/packages/server/services/chats/classes/ChatChannel/read.js b/packages/server/services/chats/classes/ChatChannel/read.ts similarity index 62% rename from packages/server/services/chats/classes/ChatChannel/read.js rename to packages/server/services/chats/classes/ChatChannel/read.ts index 0fcaa209b..d006db6d4 100644 --- a/packages/server/services/chats/classes/ChatChannel/read.js +++ b/packages/server/services/chats/classes/ChatChannel/read.ts @@ -1,14 +1,22 @@ +// @ts-ignore import { User } from "@db_models" +import type ChatChannel from "../ChatChannel" -export default async function (user, payload) { +import MessageModel from "@db/channel_messages" + +type ReadQuery = { + channel_id: string + _id?: { + $lt?: string + $gt?: string + } +} + +export default async function (this: ChatChannel, user, payload) { const { limit = 50, beforeId, afterId } = payload - let query = { + let query: ReadQuery = { channel_id: this.channel._id.toString(), - $limit: limit, - $orderby: { - $desc: "_id", - }, } if (beforeId) { @@ -23,10 +31,12 @@ export default async function (user, payload) { } } - const Message = this.scylla.model("channel_messages") - - let messages = await Message.findAsync(query, { - raw: true, + let messages = await MessageModel.find(query, { + raw: false, + limit: limit, + orderBy: { + _id: "desc", + }, }) let users = [] diff --git a/packages/server/services/chats/classes/ChatChannel/update.js b/packages/server/services/chats/classes/ChatChannel/update.ts similarity index 50% rename from packages/server/services/chats/classes/ChatChannel/update.js rename to packages/server/services/chats/classes/ChatChannel/update.ts index f9a70ffc3..cae7515c7 100644 --- a/packages/server/services/chats/classes/ChatChannel/update.js +++ b/packages/server/services/chats/classes/ChatChannel/update.ts @@ -1,4 +1,14 @@ -export default async function (user, message_id, update = {}) { +import type ChatChannel from "../ChatChannel" +import MessageModel, { + schema as ChannelMessagesSchema, +} from "@db/channel_messages" + +export default async function ( + this: ChatChannel, + user, + message_id, + update = {} as typeof ChannelMessagesSchema.fields, +) { if (!user) { throw new OperationError(400, "Missing user object") } @@ -8,7 +18,7 @@ export default async function (user, message_id, update = {}) { } // find the message - const message = await this.MessageModel.findOneAsync({ + const message = await MessageModel.findOne({ channel_id: this.channel._id.toString(), _id: message_id, }) @@ -20,17 +30,17 @@ export default async function (user, message_id, update = {}) { // validate the payload this.validateMessagePayload(update) - if (update.message) { + if (typeof update.message === "string") { message.message = String(update.message) } - if (update.attachments) { + if (Array.isArray(update.attachments)) { message.attachments = update.attachments } - message.updated_at = new Date().toISOString() + message.updated_at = new Date() - await message.saveAsync() + await message.save() - return message.toJSON() + return message.toRaw() } diff --git a/packages/server/services/chats/classes/ChatChannel/write.js b/packages/server/services/chats/classes/ChatChannel/write.ts similarity index 58% rename from packages/server/services/chats/classes/ChatChannel/write.js rename to packages/server/services/chats/classes/ChatChannel/write.ts index 9f2c95715..3277f5db3 100644 --- a/packages/server/services/chats/classes/ChatChannel/write.js +++ b/packages/server/services/chats/classes/ChatChannel/write.ts @@ -1,39 +1,45 @@ -export default async function (user, payload) { +import type ChatChannel from "../ChatChannel" + +import MessageModel from "@db/channel_messages" + +export default async function (this: ChatChannel, user, payload) { if (!user) { throw new OperationError(400, "Missing user object") } this.validateMessagePayload(payload) - const Message = this.scylla.model("channel_messages") - const _id = this.snowflake.nextId().toString() - const created_at = new Date().toISOString() + const created_at = new Date() - let message = new Message({ + const batch = this.scylla.batch() + + let message = MessageModel.obj({ _id: _id, channel_id: this.channel._id.toString(), user_id: user._id.toString(), message: payload.message && String(payload.message), - attachments: payload.attachments, + attachments: payload.attachments as any[], reply_to_id: payload.reply_to_id, - created_at: created_at.toString(), + created_at: created_at, sticker: payload.sticker, }) - await message.saveAsync() + MessageModel.batch.insert(batch, message.toRaw()) if (typeof this.onWrite === "function") { try { - await this.onWrite(user, message) + await this.onWrite(user, message, batch) } catch (error) { console.error(error) throw new OperationError(500, "Failed to execute onWrite hook") } } + await batch.execute() + const obj = { - ...message.toJSON(), + ...message.toRaw(), user: user, } diff --git a/packages/server/services/chats/classes/DMChatChannelController/index.js b/packages/server/services/chats/classes/DMChatChannelController/index.ts similarity index 79% rename from packages/server/services/chats/classes/DMChatChannelController/index.js rename to packages/server/services/chats/classes/DMChatChannelController/index.ts index 26728f58c..1bc08a527 100644 --- a/packages/server/services/chats/classes/DMChatChannelController/index.js +++ b/packages/server/services/chats/classes/DMChatChannelController/index.ts @@ -1,28 +1,31 @@ -import { User } from "@db_models" -import DMChatChannel from "@classes/DMChatChannel" import mongoose from "mongoose" +// @ts-ignore +import { User } from "@db_models" + +import DMChatChannel from "./instance" + +import ActivityModel from "@db/direct_messages_activity" +import RoomsModel from "@db/direct_messages_rooms" export function genPairKey(id1, id2) { return [id1, id2].sort().join("-") } +// TODO: extend RoomsModel and ActivityModel into one type +type ExtendedDataRoom = typeof RoomsModel.schema.fields & + typeof ActivityModel.schema.fields + export default class DMChatChannelController { constructor(server) { this.server = server } + server: any + get snowflake() { return this.server.contexts.snowflake } - get RoomsModel() { - return this.server.contexts.scylla.model("direct_messages_rooms") - } - - get ActivityModel() { - return this.server.contexts.scylla.model("direct_messages_activity") - } - get = async (from_user_id, to_user_id) => { if (typeof from_user_id !== "string") { throw new OperationError(400, "from_user_id must be a string") @@ -36,14 +39,9 @@ export default class DMChatChannelController { const pair_key = genPairKey(from_user_id, to_user_id) // search by pairkey - let room = await this.RoomsModel.findOneAsync( - { - pair_key: pair_key, - }, - { - raw: true, - }, - ) + let room = await RoomsModel.findOne({ + pair_key: pair_key, + }) // if the room doesn't exist, create it if (!room) { @@ -52,32 +50,30 @@ export default class DMChatChannelController { // ) const room_id = this.snowflake.nextId().toString() - const created_at = new Date().toISOString() + const created_at = new Date() - room = new this.RoomsModel({ + room = RoomsModel.obj({ _id: room_id, pair_key: pair_key, created_at: created_at, }) - await room.saveAsync() - - room = room.toJSON() + await room.save() } // just return the room instance - return new DMChatChannel(this, room) + return new DMChatChannel(this, room.toRaw()) } // TODO: implement pagination rooms = async (userId, { limit = 20, offset = 0 } = {}) => { - let activity = await this.ActivityModel.findAsync( + let activity = await ActivityModel.find( { user_id: userId, - $limit: limit, }, { raw: true, + limit: limit, }, ) @@ -119,7 +115,7 @@ export default class DMChatChannelController { } } - let rooms = await this.RoomsModel.findAsync( + let rooms = (await RoomsModel.find( { pair_key: { $in: pairs, @@ -128,7 +124,7 @@ export default class DMChatChannelController { { raw: true, }, - ) + )) as ExtendedDataRoom[] // insert last message_at & sort rooms = rooms.map((room) => { diff --git a/packages/server/services/chats/classes/DMChatChannel/index.js b/packages/server/services/chats/classes/DMChatChannelController/instance.ts similarity index 83% rename from packages/server/services/chats/classes/DMChatChannel/index.js rename to packages/server/services/chats/classes/DMChatChannelController/instance.ts index 7c8014a87..ecd82a2e9 100644 --- a/packages/server/services/chats/classes/DMChatChannel/index.js +++ b/packages/server/services/chats/classes/DMChatChannelController/instance.ts @@ -1,4 +1,5 @@ -import ChatChannel from "@classes/ChatChannel" +import ChatChannel from "../ChatChannel" +import ActivityModel from "@db/direct_messages_activity" function genShortMessage(messageObj) { if ( @@ -22,10 +23,6 @@ export default class DMChatChannel extends ChatChannel { this.topic = "chat:dm" } - get ActivityModel() { - return this.scylla.model("direct_messages_activity") - } - notifyActivityUpdated = async (user_id, activity) => { try { if (!user_id) { @@ -82,19 +79,19 @@ export default class DMChatChannel extends ChatChannel { // check if exists let [senderActivity, receiverActivity] = await Promise.all([ - this.ActivityModel.findOneAsync(senderActivityQuery), - this.ActivityModel.findOneAsync(receiverActivityQuery), + ActivityModel.findOne(senderActivityQuery), + ActivityModel.findOne(receiverActivityQuery), ]) if (!senderActivity) { - senderActivity = new this.ActivityModel({ + senderActivity = ActivityModel.obj({ ...senderActivityQuery, to_user_id: receiver_user_id, }) } if (!receiverActivity) { - receiverActivity = new this.ActivityModel({ + receiverActivity = ActivityModel.obj({ ...receiverActivityQuery, to_user_id: sender_user_id, }) @@ -111,17 +108,14 @@ export default class DMChatChannel extends ChatChannel { receiverActivity.short_message = short_message receiverActivity.direction = "incoming" - await Promise.all([ - senderActivity.saveAsync(), - receiverActivity.saveAsync(), - ]) + await Promise.all([senderActivity.save(), receiverActivity.save()]) // send in background try { - this.notifyActivityUpdated(sender_user_id, senderActivity.toJSON()) + this.notifyActivityUpdated(sender_user_id, senderActivity.toRaw()) this.notifyActivityUpdated( receiver_user_id, - receiverActivity.toJSON(), + receiverActivity.toRaw(), ) } catch (error) { console.error(error) diff --git a/packages/server/services/chats/classes/GroupChatChannelController/index.js b/packages/server/services/chats/classes/GroupChatChannelController/index.js index 7b815458f..48591cc25 100644 --- a/packages/server/services/chats/classes/GroupChatChannelController/index.js +++ b/packages/server/services/chats/classes/GroupChatChannelController/index.js @@ -1,7 +1,7 @@ import Groups from "@shared-classes/Spaces/Groups" import GroupChannels from "@shared-classes/Spaces/GroupChannels" -import ChatChannel from "@classes/ChatChannel" +import GroupChatChannel from "./instance" export default class GroupChatChannelController { constructor(server) { @@ -21,14 +21,12 @@ export default class GroupChatChannelController { throw new OperationError(404, "Channel not found") } - channel = channel.toJSON() + //channel = channel.toRaw() if (channel.kind !== "chat") { throw new OperationError(400, "This channel is not a chat") } - return new ChatChannel(this, channel, { - topic: "chats:channel", - }) + return new GroupChatChannel(this, channel) } } diff --git a/packages/server/services/chats/classes/GroupChatChannelController/instance.ts b/packages/server/services/chats/classes/GroupChatChannelController/instance.ts new file mode 100644 index 000000000..009f12039 --- /dev/null +++ b/packages/server/services/chats/classes/GroupChatChannelController/instance.ts @@ -0,0 +1,47 @@ +import ChatChannel from "../ChatChannel" +import type { onWriteCallbackType, onDeleteCallbackType } from "../ChatChannel" + +import LastChannelMessageIdModel from "@db/group_channels_last_message_id" +import ChannelMessagesModel from "@db/channel_messages" + +export default class GroupChatChannel extends ChatChannel { + constructor(controller, channel) { + super(controller, channel) + this.topic = "chats:channel" + } + + onWrite: onWriteCallbackType = async (user, message, batch) => { + // update last message id + LastChannelMessageIdModel.batch.update(batch, { + channel_id: this.channel._id, + _id: message._id, + }) + + try { + this.controller.server.engine.ws.senders.toTopic( + `group:${this.channel.group_id}`, + `group:${this.channel.group_id}:channels:new:message`, + { ...message.toRaw(), user: user }, + ) + } catch (err) { + console.error("Failed to send event to group", err) + } + } + + onDelete: onDeleteCallbackType = async (user, message, batch) => { + try { + // retrieve the last message + const lastMessage = await this.getFirstMessageBeforeId(message._id) + + if (lastMessage) { + // update last message id + LastChannelMessageIdModel.batch.update(batch, { + channel_id: this.channel._id, + _id: lastMessage._id, + }) + } + } catch (err) { + console.error("Failed to update channel last message id", err) + } + } +} diff --git a/packages/server/services/chats/routes/chats/channels/[group_id]/[channel_id]/last/get.js b/packages/server/services/chats/routes/chats/channels/[group_id]/[channel_id]/last/get.js new file mode 100644 index 000000000..c3a49fc63 --- /dev/null +++ b/packages/server/services/chats/routes/chats/channels/[group_id]/[channel_id]/last/get.js @@ -0,0 +1,15 @@ +export default { + useMiddlewares: ["botAuthentication", "withAuthentication"], + useContexts: ["groupChannels"], + fn: async (req, res, ctx) => { + const { group_id, channel_id } = req.params + + const channel = await ctx.groupChannels.get( + group_id, + channel_id, + req.auth.session.user_id, + ) + + return await channel.getLastMessageObj() + }, +} diff --git a/packages/server/services/chats/ws_routes/channel/send.js b/packages/server/services/chats/ws_routes/channel/send.js index f1a3f6123..1f5bbaa26 100644 --- a/packages/server/services/chats/ws_routes/channel/send.js +++ b/packages/server/services/chats/ws_routes/channel/send.js @@ -13,12 +13,16 @@ export default { throw new OperationError(400, "Missing channel_id") } + console.time("get-channel") const channel = await ctx.groupChannels.get( payload.group_id, payload.channel_id, client.userId, ) + console.timeEnd("get-channel") + console.time("write-channel") await channel.write(client.user ?? client.socket.context.user, payload) + console.timeEnd("write-channel") }, } diff --git a/packages/server/services/ems/package.json b/packages/server/services/ems/package.json index 67a965909..9af9b4f76 100644 --- a/packages/server/services/ems/package.json +++ b/packages/server/services/ems/package.json @@ -1,7 +1,7 @@ { "name": "ems", "dependencies": { - "handlebars": "^4.7.8", - "nodemailer": "^7.0.10" + "handlebars": "^4.7.9", + "nodemailer": "^8.0.5" } } diff --git a/packages/server/services/files/classes/ChunkFile/index.js b/packages/server/services/files/classes/ChunkFile/index.js index 779a0c20f..8617321eb 100755 --- a/packages/server/services/files/classes/ChunkFile/index.js +++ b/packages/server/services/files/classes/ChunkFile/index.js @@ -2,20 +2,12 @@ // Copyright (c) 2018, Quentin Busuttil All rights reserved. import fs from "node:fs" +import fsPromises from "node:fs/promises" import path from "node:path" +import { XXHash64 } from "xxhash-addon" -export function checkTotalSize( - chunkSize, // in bytes - totalChunks, // number of chunks - maxFileSize, // in bytes -) { - const totalSize = chunkSize * totalChunks - - if (totalSize > maxFileSize) { - return false - } - - return true +export function checkTotalSize(chunkSize, totalChunks, maxFileSize) { + return chunkSize * totalChunks < maxFileSize } export function checkChunkUploadHeaders(headers) { @@ -27,161 +19,180 @@ export function checkChunkUploadHeaders(headers) { ] for (const header of requiredHeaders) { - if (!headers[header] || typeof headers[header] !== "string") { + const val = headers[header] + + if (!val || typeof val !== "string") { return false } if ( - (header === "uploader-chunk-number" || - header === "uploader-chunks-total") && - !/^[0-9]+$/.test(headers[header]) + header === "uploader-chunk-number" || + header === "uploader-chunks-total" ) { - return false + if (!/^\d+$/.test(val)) return false } } return true } +export async function computeFileHash(filePath) { + const hasher = new XXHash64(Buffer.alloc(4)) + const stream = fs.createReadStream(filePath) + + for await (const chunk of stream) { + hasher.update(chunk) + } + + return hasher.digest().toString("hex") +} + export function createAssembleChunksPromise({ chunksPath, filePath, maxFileSize, + originalFileHash, }) { - return () => - new Promise(async (resolve, reject) => { - let fileSize = 0 + return async () => { + let chunks - if (!fs.existsSync(chunksPath)) { - return reject(new OperationError(500, "No chunks found")) - } - - let chunks = await fs.promises.readdir(chunksPath) + try { + chunks = await fsPromises.readdir(chunksPath) + } catch (err) { + throw new OperationError(500, "No chunks found or folder missing") + } - if (chunks.length === 0) { - return reject(new OperationError(500, "No chunks found")) - } + if (chunks.length === 0) { + throw new OperationError(500, "No chunks found") + } - // Ordenar los chunks numéricamente - chunks = chunks.sort((a, b) => { - const aNum = parseInt(a, 10) - const bNum = parseInt(b, 10) + chunks.sort((a, b) => parseInt(a, 10) - parseInt(b, 10)) - return aNum - bNum - }) + let fileSize = 0 + const writeStream = fs.createWriteStream(filePath) + try { for (const chunk of chunks) { const chunkPath = path.join(chunksPath, chunk) - if (!fs.existsSync(chunkPath)) { - return reject( - new OperationError(500, "No chunk data found"), - ) + const stat = await fsPromises.stat(chunkPath).catch(() => null) + + if (!stat) { + throw new OperationError(500, "Failed to read chunk data") } - const data = await fs.promises.readFile(chunkPath) - fileSize += data.length + fileSize += stat.size if (fileSize > maxFileSize) { - return reject( - new OperationError( - 413, - "File exceeds max total file size, aborting assembly...", - ), + throw new OperationError( + 413, + "File exceeds max total file size, aborting assembly...", ) } - await fs.promises.appendFile(filePath, data) + await new Promise((resolve, reject) => { + const readStream = fs.createReadStream(chunkPath) + + readStream.pipe(writeStream, { end: false }) + readStream.on("end", resolve) + readStream.on("error", reject) + }) } + } finally { + writeStream.end() + await new Promise((resolve) => writeStream.on("finish", resolve)) + } - return resolve({ - chunksLength: chunks.length, - filePath: filePath, - }) - }) + const fileHash = await computeFileHash(filePath) + + if ( + typeof originalFileHash === "string" && + originalFileHash !== fileHash + ) { + throw new OperationError( + 400, + `Invalid file hash check, hashes dont match\n original: [${originalFileHash}] received: [${fileHash}]`, + ) + } + + // clear assembled chunks + await fsPromises + .rm(chunksPath, { recursive: true, force: true }) + .catch(() => {}) + + return { + filePath, + fileHash, + chunksLength: chunks.length, + } + } } export async function handleChunkFile( fileStream, { chunksPath, outputDir, headers, maxFileSize, maxChunkSize }, ) { - return await new Promise(async (resolve, reject) => { - const chunkPath = path.join( - chunksPath, - headers["uploader-chunk-number"], - ) - - const chunkCount = +headers["uploader-chunk-number"] - const totalChunks = +headers["uploader-chunks-total"] + const chunkCount = parseInt(headers["uploader-chunk-number"], 10) + const totalChunks = parseInt(headers["uploader-chunks-total"], 10) + const chunkPath = path.join(chunksPath, chunkCount.toString()) - // check if file has all chunks uploaded - const isLast = chunkCount === totalChunks - 1 + const isLast = chunkCount === totalChunks - 1 - // make sure chunk is in range - if (chunkCount < 0 || chunkCount >= totalChunks) { - return reject(new OperationError(500, "Chunk is out of range")) - } - - let dataWritten = 0 + if (chunkCount < 0 || chunkCount >= totalChunks) { + throw new OperationError(500, "Chunk is out of range") + } - let writeStream = fs.createWriteStream(chunkPath) + await fsPromises.mkdir(chunksPath, { recursive: true }) + const writeStream = fs.createWriteStream(chunkPath) - writeStream.on("error", (err) => { - reject(err) - }) + let dataWritten = 0 - writeStream.on("close", () => { - if (maxChunkSize !== undefined) { - if (dataWritten > maxChunkSize) { - reject( - new OperationError( - 413, - "Chunk size exceeds max chunk size, aborting upload...", - ), - ) - return - } + try { + for await (const chunk of fileStream) { + dataWritten += chunk.byteLength - // estimate total file size, - // if estimation exceeds maxFileSize, abort upload - if (chunkCount === 0 && totalChunks > 0) { - if (dataWritten * (totalChunks - 1) > maxFileSize) { - reject( - new OperationError( - 413, - "File estimated size exceeds max total file size, aborting upload...", - ), - ) - return - } - } + if (maxChunkSize !== undefined && dataWritten > maxChunkSize) { + throw new OperationError( + 413, + "Chunk size exceeds max chunk size, aborting upload...", + ) } - if (isLast) { - // const mimetype = mimetypes.lookup( - // headers["uploader-original-name"], - // ) - // const extension = mimetypes.extension(mimetype) - - let filename = nanoid() - - return resolve( - createAssembleChunksPromise({ - // build data - chunksPath: chunksPath, - filePath: path.resolve(outputDir, filename), - maxFileSize: maxFileSize, - }), + if (!writeStream.write(chunk)) { + await new Promise((resolve) => + writeStream.once("drain", resolve), ) } + } - return resolve(null) - }) + writeStream.end() + await new Promise((resolve) => writeStream.once("finish", resolve)) + } catch (error) { + writeStream.destroy() + + await fsPromises.rm(chunkPath, { force: true }).catch(() => {}) + throw error + } - fileStream.on("data", (buffer) => { - dataWritten += buffer.byteLength + if (chunkCount === 0 && totalChunks > 0 && maxChunkSize !== undefined) { + if (dataWritten * (totalChunks - 1) > maxFileSize) { + await fsPromises.rm(chunkPath, { force: true }).catch(() => {}) + + throw new OperationError( + 413, + "File estimated size exceeds max total file size, aborting upload...", + ) + } + } + + if (isLast) { + return createAssembleChunksPromise({ + chunksPath, + filePath: path.resolve(outputDir, nanoid()), + maxFileSize, + originalFileHash: headers?.["uploader-file-hash"], }) + } - fileStream.pipe(writeStream) - }) + return null } diff --git a/packages/server/services/files/files.service.js b/packages/server/services/files/files.service.js index 6d11f4711..e68b56a4d 100755 --- a/packages/server/services/files/files.service.js +++ b/packages/server/services/files/files.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import StorageClient from "@shared-classes/StorageClient" diff --git a/packages/server/services/files/package.json b/packages/server/services/files/package.json index a7e759719..409e099e0 100644 --- a/packages/server/services/files/package.json +++ b/packages/server/services/files/package.json @@ -5,6 +5,7 @@ "fluent-ffmpeg": "^2.1.2", "mime-types": "^2.1.35", "p-map": "4", - "sharp": "0.32.6" + "sharp": "0.32.6", + "xxhash-addon": "^2.1.0" } } diff --git a/packages/server/services/files/routes/upload/chunk/post.js b/packages/server/services/files/routes/upload/chunk/post.js index 19ffe9524..46a262109 100644 --- a/packages/server/services/files/routes/upload/chunk/post.js +++ b/packages/server/services/files/routes/upload/chunk/post.js @@ -76,10 +76,13 @@ export default { } const payload = { + filePath: assemble.filePath, + fileHash: assemble.fileHash, + user_id: req.auth.session.user_id, uploadId: uploadId, - filePath: assemble.filePath, workPath: workPath, + originalFilename: req.headers["uploader-original-name"], transformations: transformations, s3Provider: config.useProvider, diff --git a/packages/server/services/groups/groups.service.js b/packages/server/services/groups/groups.service.js index 802c00b2e..abe0b8951 100644 --- a/packages/server/services/groups/groups.service.js +++ b/packages/server/services/groups/groups.service.js @@ -3,7 +3,7 @@ import { Server } from "linebridge" import { Worker as SnowflakeWorker } from "snowflake-uuid" import DbManager from "@shared-classes/DbManager" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import RedisClient from "@shared-classes/RedisClient" import SharedMiddlewares from "@shared-middlewares" diff --git a/packages/server/services/groups/routes/groups/[group_id]/canPerform/[action]/get.js b/packages/server/services/groups/routes/groups/[group_id]/canPerform/[action]/get.js index c0b1ceb12..32c0bb2f2 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/canPerform/[action]/get.js +++ b/packages/server/services/groups/routes/groups/[group_id]/canPerform/[action]/get.js @@ -6,7 +6,7 @@ export default { fn: async (req) => { const { group_id, action } = req.params - const group = await Groups.model.findOneAsync({ + const group = await Groups.model.findOne({ _id: group_id, }) diff --git a/packages/server/services/groups/routes/groups/[group_id]/channels/get.js b/packages/server/services/groups/routes/groups/[group_id]/channels/get.js index e04a3192a..cf93a193b 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/channels/get.js +++ b/packages/server/services/groups/routes/groups/[group_id]/channels/get.js @@ -18,10 +18,10 @@ export default { req.auth.session.user_id, ) - channels = channels.map((channel) => channel.toJSON()) + channels = channels.map((channel) => channel.toRaw()) const channelOrder = await GroupChannels.orderModel - .findOneAsync({ + .findOne({ group_id: req.params.group_id, }) .catch(() => null) @@ -43,6 +43,9 @@ export default { }) } - return channels + return { + total_items: channels.length, + items: channels, + } }, } diff --git a/packages/server/services/groups/routes/groups/[group_id]/join/post.js b/packages/server/services/groups/routes/groups/[group_id]/join/post.js index 281d144c9..aef1e9b5b 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/join/post.js +++ b/packages/server/services/groups/routes/groups/[group_id]/join/post.js @@ -64,7 +64,7 @@ export default { invite.usages++ // save the invite - await invite.saveAsync() + await invite.save() return membership }, diff --git a/packages/server/services/groups/routes/groups/[group_id]/leave/post.js b/packages/server/services/groups/routes/groups/[group_id]/leave/post.js index 3f566593f..944e650a0 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/leave/post.js +++ b/packages/server/services/groups/routes/groups/[group_id]/leave/post.js @@ -18,19 +18,27 @@ export default { ) } - // check if the user is a member of the group - const membership = group.memberships.find( - (membership) => membership.user_id === req.auth.user_id, + let membership = await GroupMemberships.model.find( + { + user_id: req.auth.user_id, + group_id: req.params.group_id, + }, + { + raw: true, + }, ) + membership = membership[0] + if (!membership) { throw new OperationError(403, "You are not a member of this group") } await GroupMemberships.delete( - membership._id.toString(), - req.params.group_id, req.auth.user_id, + membership._id, + req.params.group_id, + group, ) return membership diff --git a/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/delete.js b/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/delete.js index 97bf0140b..3c4ca9597 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/delete.js +++ b/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/delete.js @@ -5,6 +5,10 @@ import GroupPermissions from "@shared-classes/Spaces/GroupPermissions" export default { useMiddlewares: ["withAuthentication"], fn: async (req) => { + if (typeof req.body.user_id !== "string") { + throw new OperationError(400, "user_id must be a string") + } + const group = await Groups.get( req.params.group_id, req.auth.session.user_id, @@ -27,6 +31,10 @@ export default { ) } - return await GroupMemberships.delete(req.params.member_id, group._id) + return await GroupMemberships.delete( + req.params.user_id, + req.params.member_id, + group._id, + ) }, } diff --git a/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/get.js b/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/get.js index e046e4d36..ec14013cc 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/get.js +++ b/packages/server/services/groups/routes/groups/[group_id]/members/[member_id]/get.js @@ -5,6 +5,10 @@ import GroupPermissions from "@shared-classes/Spaces/GroupPermissions" export default { useMiddlewares: ["withAuthentication"], fn: async (req) => { + if (typeof req.body.user_id !== "string") { + throw new OperationError(400, "user_id must be a string") + } + const group = await Groups.get( req.params.group_id, req.auth.session.user_id, @@ -29,6 +33,7 @@ export default { let membership = await GroupMemberships.get( group._id, + req.body.user_id, req.params.member_id, ) @@ -36,7 +41,7 @@ export default { throw new OperationError(404, "Membership not found") } - membership = membership.toJSON() + membership = membership.toRaw() if (!Array.isArray(membership.roles)) { membership.roles = [] diff --git a/packages/server/services/groups/routes/groups/[group_id]/members/get.js b/packages/server/services/groups/routes/groups/[group_id]/members/get.js index 612b5f3ba..0ddbc3121 100644 --- a/packages/server/services/groups/routes/groups/[group_id]/members/get.js +++ b/packages/server/services/groups/routes/groups/[group_id]/members/get.js @@ -64,7 +64,7 @@ export default { items = items.map((item) => { return { - ...item.toJSON(), + ...item.toRaw(), user: users.get(item.user_id), } }) diff --git a/packages/server/services/groups/routes/groups/my/get.js b/packages/server/services/groups/routes/groups/my/get.js index aef78e483..6b969079a 100644 --- a/packages/server/services/groups/routes/groups/my/get.js +++ b/packages/server/services/groups/routes/groups/my/get.js @@ -10,12 +10,8 @@ export default { req.auth.session.user_id, ) - if (groups.toJSON) { - groups = groups.toJSON() - } - const sorted = await Groups.sortModel - .findOneAsync( + .findOne( { user_id: req.auth.session.user_id, }, diff --git a/packages/server/services/groups/ws_routes/groups/sync.ts b/packages/server/services/groups/ws_routes/groups/sync.ts new file mode 100644 index 000000000..d85a6cf2c --- /dev/null +++ b/packages/server/services/groups/ws_routes/groups/sync.ts @@ -0,0 +1,72 @@ +import { DateTime, Duration } from "luxon" + +import MembershipsModel from "@db/group_memberships_ref" + +type SyncPayload = { + group_id: string + data_sync_time?: string + channels_sync_time?: string + members_sync_time?: string +} + +type EventBefore = { + members?: any[] +} + +type CacheMiss = { + members?: boolean + channels?: boolean +} + +const MAX_SYNC_TIME_DIFF_HOURS = 24 +const MAX_NEW_MEMBERSHIPS_UNTIL_INVALIDATE = 10 + +export default { + useContexts: ["scylla"], + fn: async (client: RTEClient, payload: SyncPayload, ctx: any) => { + if (!payload.group_id) { + throw new OperationError(400, "Missing group_id to sync with") + } + + console.log("groups::sync", payload) + + let eventsBeforeSyncTime: EventBefore = {} + let cacheMiss: CacheMiss = {} + + if (payload.members_sync_time) { + if ( + DateTime.fromISO(payload.members_sync_time).diffNow().hours > + MAX_SYNC_TIME_DIFF_HOURS + ) { + cacheMiss.members = true + } else { + const newMemberships = await MembershipsModel.find( + { + group_id: payload.group_id, + created_at: { + $gt: new Date(payload.members_sync_time), + }, + }, + { + limit: MAX_NEW_MEMBERSHIPS_UNTIL_INVALIDATE + 1, + }, + ) + + if ( + newMemberships.length > MAX_NEW_MEMBERSHIPS_UNTIL_INVALIDATE + ) { + cacheMiss.members = true + } else { + eventsBeforeSyncTime.members = newMemberships + } + } + } + + console.log({ eventsBeforeSyncTime, cacheMiss }) + + return { + cache_miss: cacheMiss, + events: eventsBeforeSyncTime, + } + }, +} diff --git a/packages/server/services/main/main.service.js b/packages/server/services/main/main.service.js index 0bb405b90..e9ed2e93b 100755 --- a/packages/server/services/main/main.service.js +++ b/packages/server/services/main/main.service.js @@ -1,6 +1,7 @@ import { Server } from "linebridge" +import path from "path" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import UserConnections from "@shared-classes/UserConnections" @@ -60,14 +61,19 @@ export default class API extends Server { contexts = { db: new DbManager(), - scylla: (global.scylla = new ScyllaDb()), + scylla: (global.scylla = new ScyllaDb({ + modelsPath: path.resolve(__dirname, "../../db"), + })), redis: RedisClient(), userConnections: new UserConnections(this), } initialize = [ () => this.contexts.db.initialize(), - () => this.contexts.scylla.initialize(), + () => + this.contexts.scylla.initialize({ + sync: true, + }), () => this.contexts.redis.initialize(), ] diff --git a/packages/server/services/main/routes/flags/ack/[flag_id]/post.js b/packages/server/services/main/routes/flags/ack/[flag_id]/post.js new file mode 100644 index 000000000..e2b9dd0e3 --- /dev/null +++ b/packages/server/services/main/routes/flags/ack/[flag_id]/post.js @@ -0,0 +1,35 @@ +import { User, Config } from "@db_models" + +export default { + useMiddlewares: ["withAuthentication"], + useContexts: ["scylla"], + fn: async (req, res, ctx) => { + const { flag_id } = req.params + + const flags_config = await Config.findOne({ key: "flags" }) + + if (!flags_config || !Array.isArray(flags_config.value)) { + throw new OperationError(400, "Server has not configured flags") + } + + if (!flags_config.value.includes(flag_id)) { + throw new OperationError(400, "Flag not valid") + } + + const user = await User.findById(req.auth.user_id) + + if (!Array.isArray(user.flags)) { + user.flags = Array() + } + + if (!user.flags.includes(flag_id)) { + user.flags.push(flag_id) + await user.save() + } + + return { + ok: true, + flags: user.flags, + } + }, +} diff --git a/packages/server/services/marketplace/marketplace.service.js b/packages/server/services/marketplace/marketplace.service.js index f80ec40a8..7ee29a959 100755 --- a/packages/server/services/marketplace/marketplace.service.js +++ b/packages/server/services/marketplace/marketplace.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import CacheService from "@shared-classes/CacheService" import StorageClient from "@shared-classes/StorageClient" diff --git a/packages/server/services/music/music.service.js b/packages/server/services/music/music.service.js index 1d3169f8e..72b15d831 100755 --- a/packages/server/services/music/music.service.js +++ b/packages/server/services/music/music.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" diff --git a/packages/server/services/notifications/notifications.service.js b/packages/server/services/notifications/notifications.service.js index 52ea6f89a..deefd6536 100644 --- a/packages/server/services/notifications/notifications.service.js +++ b/packages/server/services/notifications/notifications.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" diff --git a/packages/server/services/posts/posts.service.js b/packages/server/services/posts/posts.service.js index a81767ccc..6ba05f4e8 100644 --- a/packages/server/services/posts/posts.service.js +++ b/packages/server/services/posts/posts.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import TaskQueueManager from "@shared-classes/TaskQueueManager" diff --git a/packages/server/services/rtc/classes/MediaChannel/handlers/joinClient.ts b/packages/server/services/rtc/classes/MediaChannel/handlers/joinClient.ts index cfe16c0a7..f9e27298a 100644 --- a/packages/server/services/rtc/classes/MediaChannel/handlers/joinClient.ts +++ b/packages/server/services/rtc/classes/MediaChannel/handlers/joinClient.ts @@ -9,6 +9,8 @@ async function joinClientHandler(this: any, client: RTCClient) { deafened: false, } + client.channel_id = this.channelId + // add to set of clients this.clients.add(client) @@ -44,17 +46,21 @@ async function joinClientHandler(this: any, client: RTCClient) { } // publish to group topic - await this.sendToGroupTopic("client:vc:join", { - userId: client.userId, - channelId: this.channelId, - user: { - _id: client.context.user._id, - username: client.context.user.username, - avatar: client.context.user.avatar, - }, - voiceState: client.voiceState, - channelClients: this.getConnectedClientsSerialized(), - }) + this.events.emit("client:join", this, client) + // await this.sendToGroupTopic("client:vc:join", { + // userId: client.userId, + // channelId: this.channelId, + // user: { + // _id: client.context.user._id, + // username: client.context.user.username, + // avatar: client.context.user.avatar, + // }, + // voiceState: client.voiceState, + // channelClients: this.getConnectedClientsSerialized(), + // }) + // + + console.log("joinClient", client.userId, client.channel_id) return { started_at: this.started_at, diff --git a/packages/server/services/rtc/classes/MediaChannel/handlers/leaveClient.ts b/packages/server/services/rtc/classes/MediaChannel/handlers/leaveClient.ts index c19ee2bf4..aa195cb5f 100644 --- a/packages/server/services/rtc/classes/MediaChannel/handlers/leaveClient.ts +++ b/packages/server/services/rtc/classes/MediaChannel/handlers/leaveClient.ts @@ -77,11 +77,13 @@ async function leaveClientHandler( } // publish to group topic - await this.sendToGroupTopic("client:vc:left", { - userId: clientInst.userId, - channelId: this.channelId, - channelClients: this.getConnectedClientsSerialized(), - }) + this.events.emit("client:leave", this, clientInst) + + // await this.sendToGroupTopic("client:vc:left", { + // userId: clientInst.userId, + // channelId: this.channelId, + // channelClients: this.getConnectedClientsSerialized(), + // }) if (emitEventToSelf === true) { // notify the client that they left the channel diff --git a/packages/server/services/rtc/classes/MediaChannel/index.ts b/packages/server/services/rtc/classes/MediaChannel/index.ts index c6db3ff0e..d0560fd86 100644 --- a/packages/server/services/rtc/classes/MediaChannel/index.ts +++ b/packages/server/services/rtc/classes/MediaChannel/index.ts @@ -1,4 +1,5 @@ import * as mediasoup from "mediasoup" +import EventEmitter from "@foxify/events" import consumeHandler from "./handlers/consume" import produceHandler from "./handlers/produce" @@ -20,6 +21,7 @@ export default class MediaChannel { mediaCodecs: any[] started_at: Date closed: Boolean = false + events: EventEmitter = new EventEmitter() static defaultMediaCodecs = [ { @@ -92,15 +94,17 @@ export default class MediaChannel { ) }) - try { - this.sendToGroupTopic("vc:started", { - ...this.data, - channelId: this.channelId, - started_at: this.started_at, - }) - } catch (err) { - console.error(err) - } + this.events.emit("started", this) + + // try { + // this.sendToGroupTopic("vc:started", { + // ...this.data, + // channelId: this.channelId, + // started_at: this.started_at, + // }) + // } catch (err) { + // console.error(err) + // } } catch (error) { console.error( `[CHANNEL:${this.channelId}] Error initializing `, @@ -168,13 +172,15 @@ export default class MediaChannel { console.info(`[CHANNEL:${this.channelId}] closed`) - try { - this.sendToGroupTopic("vc:ended", { - channelId: this.channelId, - }) - } catch (err) { - console.error(err) - } + this.events.emit("closed", this) + + // try { + // this.sendToGroupTopic("vc:ended", { + // channelId: this.channelId, + // }) + // } catch (err) { + // console.error(err) + // } if (this.params.controller) { try { @@ -217,17 +223,18 @@ export default class MediaChannel { clientVoiceState: client.voiceState, }) - this.sendToGroupTopic("client:vc:event", { - event: payload.event, - userId: client.userId, - channelId: this.channelId, - user: { - _id: client.context.user._id, - username: client.context.user.username, - avatar: client.context.user.avatar, - }, - data: payload.data, - }) + this.events.emit("client:event", this, client, payload) + // this.sendToGroupTopic("client:vc:event", { + // event: payload.event, + // userId: client.userId, + // channelId: this.channelId, + // user: { + // _id: client.context.user._id, + // username: client.context.user.username, + // avatar: client.context.user.avatar, + // }, + // data: payload.data, + // }) } async handleSoundpadDispatch(client: RTCClient, payload: any) { @@ -286,7 +293,9 @@ export default class MediaChannel { return Array.from(this.clients).map((c) => { return { userId: c.userId, + user_id: c.userId, voiceState: c.voiceState, + voice_state: c.voiceState, user: { _id: c.context.user?._id, username: c.context.user?.username, @@ -361,20 +370,20 @@ export default class MediaChannel { * @param {Object} payload * @return {Promise} */ - async sendToGroupTopic(event: string, payload: any): Promise { - const topic = `group:${this.data.group_id}` - - try { - return await (globalThis as any).websockets.senders.toTopic( - topic, - `${topic}:${event}`, - payload, - ) - } catch (error) { - console.error( - `[CHANNEL:${this.channelId}] Error sending to group topic`, - error, - ) - } - } + // async sendToGroupTopic(event: string, payload: any): Promise { + // const topic = `group:${this.data.group_id}` + + // try { + // return await (globalThis as any).websockets.senders.toTopic( + // topic, + // `${topic}:${event}`, + // payload, + // ) + // } catch (error) { + // console.error( + // `[CHANNEL:${this.channelId}] Error sending to group topic`, + // error, + // ) + // } + // } } diff --git a/packages/server/services/rtc/classes/MediaChannel/producer.ts b/packages/server/services/rtc/classes/MediaChannel/producer.ts index 88d57b999..bd5028124 100644 --- a/packages/server/services/rtc/classes/MediaChannel/producer.ts +++ b/packages/server/services/rtc/classes/MediaChannel/producer.ts @@ -72,16 +72,18 @@ export default class Producer { this.serialize(), ) - this.instance.sendToGroupTopic("client:vc:producer:open", { - userId: this.client.userId, - channelId: this.channelId, - producer: this.serialize(), - user: { - _id: this.client.context.user._id, - username: this.client.context.user.username, - avatar: this.client.context.user.avatar, - }, - }) + this.instance.events.emit("producer:open", this) + + // this.instance.sendToGroupTopic("client:vc:producer:open", { + // userId: this.client.userId, + // channelId: this.channelId, + // producer: this.serialize(), + // user: { + // _id: this.client.context.user._id, + // username: this.client.context.user.username, + // avatar: this.client.context.user.avatar, + // }, + // }) const instanceProducers = this.instance.producers @@ -117,23 +119,25 @@ export default class Producer { ) } - try { - this.instance.sendToGroupTopic("client:vc:producer:close", { - userId: this.client.userId, - channelId: this.channelId, - producer: this.serialize(), - user: { - _id: this.client.context.user._id, - username: this.client.context.user.username, - avatar: this.client.context.user.avatar, - }, - }) - } catch (error) { - console.error( - `[CHANNEL:${this.channelId}] Error notifying clients about producer close:`, - error, - ) - } + this.instance.events.emit("producer:close", this) + + // try { + // this.instance.sendToGroupTopic("client:vc:producer:close", { + // userId: this.client.userId, + // channelId: this.channelId, + // producer: this.serialize(), + // user: { + // _id: this.client.context.user._id, + // username: this.client.context.user.username, + // avatar: this.client.context.user.avatar, + // }, + // }) + // } catch (error) { + // console.error( + // `[CHANNEL:${this.channelId}] Error notifying clients about producer close:`, + // error, + // ) + // } try { const instanceProducers = this.instance.producers diff --git a/packages/server/services/rtc/classes/MediaChannel/types.d.ts b/packages/server/services/rtc/classes/MediaChannel/types.d.ts index 32b88ebe6..b821b790e 100644 --- a/packages/server/services/rtc/classes/MediaChannel/types.d.ts +++ b/packages/server/services/rtc/classes/MediaChannel/types.d.ts @@ -10,6 +10,7 @@ export type MediaChannelParams = { } export type RTCClient = RTEClient & { + channel_id?: string transports?: Map voiceState?: { muted: boolean diff --git a/packages/server/services/rtc/classes/MediaChannelsController/handlers/createChannelInstance.js b/packages/server/services/rtc/classes/MediaChannelsController/handlers/createChannelInstance.js index cabfd1162..e07929e36 100644 --- a/packages/server/services/rtc/classes/MediaChannelsController/handlers/createChannelInstance.js +++ b/packages/server/services/rtc/classes/MediaChannelsController/handlers/createChannelInstance.js @@ -1,10 +1,9 @@ import MediaChannel from "@classes/MediaChannel/index.ts" +import GroupChannelsModel from "@db/group_channels" export default async function (groupId, channelId) { - const GroupChannelsModel = global.scylla.model("group_channels") - // get the channel - const channel = await GroupChannelsModel.findOneAsync({ + const channel = await GroupChannelsModel.findOne({ _id: channelId, group_id: groupId, }) @@ -15,7 +14,7 @@ export default async function (groupId, channelId) { // create the channel instance const channelInstance = new MediaChannel({ - data: channel.toJSON(), + data: channel.toRaw(), channelId: channelId, mediaCodecs: this.constructor.allowedMediaCodecs, webrtcServer: this.webrtcServer, @@ -26,6 +25,77 @@ export default async function (groupId, channelId) { // initialize the channel instance await channelInstance.initialize() + channelInstance.events.on("started", (_ch) => { + this.sendToGroupTopic(groupId, "vc:started", { + ..._ch.data, + started_at: _ch.started_at, + channelId: channelId, + }) + }) + + channelInstance.events.on("ended", (_ch) => { + this.sendToGroupTopic(groupId, "vc:ended", { channelId: _ch.channelId }) + }) + + channelInstance.events.on("client:join", (_ch, client) => { + this.sendToGroupTopic(groupId, "client:vc:join", { + userId: client.userId, + channelId: _ch.channelId, + user: { + _id: client.context.user._id, + username: client.context.user.username, + avatar: client.context.user.avatar, + }, + voiceState: client.voiceState, + channelClients: _ch.getConnectedClientsSerialized(), + }) + }) + channelInstance.events.on("client:leave", (_ch, client) => { + this.sendToGroupTopic(groupId, "client:vc:left", { + userId: client.userId, + channelId: _ch.channelId, + channelClients: _ch.getConnectedClientsSerialized(), + }) + }) + channelInstance.events.on("client:event", (_ch, client, payload) => { + this.sendToGroupTopic(groupId, "client:vc:event", { + event: payload.event, + userId: client.userId, + channelId: _ch.channelId, + user: { + _id: client.context.user._id, + username: client.context.user.username, + avatar: client.context.user.avatar, + }, + data: payload.data, + }) + }) + + channelInstance.events.on("producer:open", (producer) => { + this.sendToGroupTopic(groupId, "client:vc:producer:open", { + userId: producer.client.userId, + channelId: producer.channelId, + producer: producer.serialize(), + user: { + _id: producer.client.context.user._id, + username: producer.client.context.user.username, + avatar: producer.client.context.user.avatar, + }, + }) + }) + channelInstance.events.on("producer:close", (producer) => { + this.sendToGroupTopic(groupId, "client:vc:producer:close", { + userId: producer.client.userId, + channelId: producer.channelId, + producer: producer.serialize(), + user: { + _id: producer.client.context.user._id, + username: producer.client.context.user.username, + avatar: producer.client.context.user.avatar, + }, + }) + }) + // add the channel instance to the instances map this.instances.set(channelId, channelInstance) diff --git a/packages/server/services/rtc/classes/MediaChannelsController/handlers/getUserJoinedGroupsIds.js b/packages/server/services/rtc/classes/MediaChannelsController/handlers/getUserJoinedGroupsIds.js index b23cd11c4..5fe012f93 100644 --- a/packages/server/services/rtc/classes/MediaChannelsController/handlers/getUserJoinedGroupsIds.js +++ b/packages/server/services/rtc/classes/MediaChannelsController/handlers/getUserJoinedGroupsIds.js @@ -1,7 +1,7 @@ -export default async function (userId) { - const GroupMembershipsModel = global.scylla.model("group_memberships") +import GroupMembershipsModel from "@db/group_memberships" - const memberships = await GroupMembershipsModel.findAsync( +export default async function (userId) { + const memberships = await GroupMembershipsModel.find( { user_id: userId, }, diff --git a/packages/server/services/rtc/classes/MediaChannelsController/handlers/joinClient.js b/packages/server/services/rtc/classes/MediaChannelsController/handlers/joinClient.js index 44c71b98e..df3bf6742 100644 --- a/packages/server/services/rtc/classes/MediaChannelsController/handlers/joinClient.js +++ b/packages/server/services/rtc/classes/MediaChannelsController/handlers/joinClient.js @@ -1,8 +1,8 @@ +import GroupChannelsModel from "@db/group_channels" + export default async function (client, channelId) { try { - const GroupChannelsModel = global.scylla.model("group_channels") - - const channel = await GroupChannelsModel.findOneAsync( + const channel = await GroupChannelsModel.findOne( { _id: channelId, }, diff --git a/packages/server/services/rtc/classes/MediaChannelsController/handlers/validateGroupAccess.js b/packages/server/services/rtc/classes/MediaChannelsController/handlers/validateGroupAccess.js index c60b500ee..4b49bd65f 100644 --- a/packages/server/services/rtc/classes/MediaChannelsController/handlers/validateGroupAccess.js +++ b/packages/server/services/rtc/classes/MediaChannelsController/handlers/validateGroupAccess.js @@ -1,8 +1,8 @@ -export default async function (userId, groupId) { - const GroupsModel = global.scylla.model("groups") - const GroupMembershipsModel = global.scylla.model("group_memberships") +import GroupsModel from "@db/groups" +import GroupMembershipsRefModel from "@db/group_memberships_ref" - const group = await GroupsModel.findOneAsync( +export default async function (userId, groupId) { + const group = await GroupsModel.findOne( { _id: groupId }, { raw: true, @@ -13,7 +13,7 @@ export default async function (userId, groupId) { throw new Error("Group not found") } - const memberships = await GroupMembershipsModel.findAsync( + const memberships = await GroupMembershipsRefModel.find( { group_id: group._id, }, diff --git a/packages/server/services/rtc/classes/MediaChannelsController/index.js b/packages/server/services/rtc/classes/MediaChannelsController/index.js index 9f6ce6848..50540dce7 100644 --- a/packages/server/services/rtc/classes/MediaChannelsController/index.js +++ b/packages/server/services/rtc/classes/MediaChannelsController/index.js @@ -141,4 +141,28 @@ export default class MediaChannelsController { client.transports.clear() } } + + /** + * Send an event to the group topic + * @param {String} group_id + * @param {String} event + * @param {Object} payload + * @return {Promise} + */ + async sendToGroupTopic(group_id, event, payload) { + const topic = `group:${group_id}` + + try { + return await globalThis.websockets.senders.toTopic( + topic, + `${topic}:${event}`, + payload, + ) + } catch (error) { + console.error( + `[CHANNEL:${this.channelId}] Error sending to group topic`, + error, + ) + } + } } diff --git a/packages/server/services/rtc/classes/UserCalls/index.js b/packages/server/services/rtc/classes/UserCalls/index.js deleted file mode 100644 index 655bc4a2d..000000000 --- a/packages/server/services/rtc/classes/UserCalls/index.js +++ /dev/null @@ -1,39 +0,0 @@ -export default class UserCalls { - constructor(server) { - this.server = server - } - - async dispatch(client, payload = {}) { - const { userId } = payload - - if (!client) { - throw new OperationError(400, "Missing rte client") - } - - if (!userId) { - throw new OperationError(400, "Missing userId") - } - - console.log("calling user", userId) - - // try to emit event to the user - const targetClients = - await this.server.engine.ws.find.clientsByUserId(userId) - - for (const targetClient of targetClients) { - await targetClient.emit("call:incoming", { - userId: client.userId, - alternativeSfx: payload.alternativeSfx, - }) - } - - // create a new media channel for only this two users - - return { - userId: userId, - alternativeSfx: payload.alternativeSfx, - } - } - - async initialize() {} -} diff --git a/packages/server/services/rtc/classes/UserCalls/index.ts b/packages/server/services/rtc/classes/UserCalls/index.ts new file mode 100644 index 000000000..da7c3c543 --- /dev/null +++ b/packages/server/services/rtc/classes/UserCalls/index.ts @@ -0,0 +1,117 @@ +import MediaChannel from "../MediaChannel" +import * as mediasoup from "mediasoup" +import getAnnouncedIp from "../../utils/getAnnouncedIp" + +type DispatchCallPayload = { + userId: string + alternativeSfx?: string +} + +export default class UserCalls { + constructor(server: any) { + this.server = server + } + server: any + + worker: mediasoup.types.Worker = null + webrtcServer: mediasoup.types.WebRtcServer = null + + instances: Map = new Map() + usersMap: Map = new Map() + + async initialize() { + this.worker = await mediasoup.createWorker() + this.webrtcServer = await this.worker.createWebRtcServer({ + listenInfos: [ + { + protocol: "udp", + ip: "0.0.0.0", + announcedIp: getAnnouncedIp(), + port: 41000, + }, + { + protocol: "tcp", + ip: "0.0.0.0", + announcedIp: getAnnouncedIp(), + port: 41000, + }, + ], + }) + } + + async dispatch(client: RTEClient, payload: DispatchCallPayload) { + const { userId, alternativeSfx } = payload + + if (!client) { + throw new OperationError(400, "Missing rte client") + } + + if (!userId) { + throw new OperationError(400, "Missing userId") + } + + console.log("calling user", userId) + + // try to emit event to the user + const targetClients = + await this.server.engine.ws.find.clientsByUserId(userId) + + for (const targetClient of targetClients) { + await targetClient.emit("call:incoming", { + userId: client.userId, + alternativeSfx: alternativeSfx, + }) + } + + // create a new media channel for only this two users + const roomId = `DM:${global.nanoid()}` + + const room = new MediaChannel({ + data: { + _id: roomId, + }, + channelId: roomId, + worker: this.worker, + webrtcServer: this.webrtcServer, + controller: this, + }) + + await room.initialize() + + this.instances.set(roomId, room) + this.usersMap.set(client.userId, roomId) + + return await room.joinClient(client) + } + + async leave(client: RTEClient, payload: any) { + if (!client) { + throw new OperationError(400, "Missing rte client") + } + + const channel = this.getClientChannel(client) + + if (!channel) { + throw new Error("No media channel joined") + } + + this.usersMap.delete(client.userId) + return channel.leaveClient(client) + } + + getClientChannel(client: RTEClient): MediaChannel { + const currentUserMediaChannel = this.usersMap.get(client.userId) + + if (!currentUserMediaChannel) { + throw new Error("No media channel joined") + } + + const channelInstance = this.instances.get(currentUserMediaChannel) + + if (!channelInstance) { + throw new Error("Media channel instance not found") + } + + return channelInstance + } +} diff --git a/packages/server/services/rtc/routes/rtc/groups/[group_id]/state/get.js b/packages/server/services/rtc/routes/rtc/groups/[group_id]/state/get.js index c622545bb..31b203c95 100644 --- a/packages/server/services/rtc/routes/rtc/groups/[group_id]/state/get.js +++ b/packages/server/services/rtc/routes/rtc/groups/[group_id]/state/get.js @@ -1,4 +1,9 @@ import UserConnections from "@shared-classes/UserConnections" +import GroupMemberships from "@shared-classes/Spaces/GroupMemberships" +import GroupChannels from "@shared-classes/Spaces/GroupChannels" + +import GroupsModel from "@db/groups" +import LastChannelMessageIdModel from "@db/group_channels_last_message_id" export default { useMiddlewares: ["withAuthentication"], @@ -6,64 +11,83 @@ export default { fn: async (req, res, ctx) => { const { group_id } = req.params - const GroupsModel = ctx.scylla.model("groups") - const GroupMembershipsModel = ctx.scylla.model("group_memberships") - - const group = await GroupsModel.findOneAsync( + const group = await GroupsModel.findOne( { _id: group_id }, - { - raw: true, - }, + { raw: true }, ) if (!group) { throw new OperationError(404, "Group not found") } - group.memberships = await GroupMembershipsModel.findAsync( - { - group_id: group_id, - }, - { - raw: true, - }, - ) - - const membership = group.memberships.find( - (entry) => entry.user_id === req.auth.session.user_id, - ) - - if (!membership) { + if ( + !(await GroupMemberships.isUserIdOnMembers( + req.auth.session.user_id, + group_id, + )) + ) { throw new OperationError(403, "You are not a member of this group") } - let channels = await ctx.mediaChannels.findChannelsByGroupId(group_id) + let state = { + group: group, + total_members: 0, + } + + console.time("getLastChannelsMessages") + let channels = await GroupChannels.getAllByGroupId( + group, + req.auth.session.user_id, + ) + + const channelsIds = channels.map((channel) => channel._id) - // map channel clients - channels = channels.map((channel) => { - return { - _id: channel.data._id, - clients: channel.getConnectedClientsSerialized(), - producers: channel.getProducersSerialized(), - started_at: channel.started_at, - } + state.last_channels_messages = await LastChannelMessageIdModel.find({ + channel_id: { + $in: channelsIds, + }, }) + console.timeEnd("getLastChannelsMessages") - // get connected users - group.connected_members = await UserConnections.isUsersConnected( - ctx.redis.client, - group.memberships.map((member) => member.user_id), - ) + console.time("getTotalMembersByGroupId") + state.total_members = + await GroupMemberships.getTotalMembersByGroupId(group_id) + console.timeEnd("getTotalMembersByGroupId") - // filter & map connected users ids - group.connected_members = group.connected_members.filter( - (c) => c.connected, - ) - group.connected_members = group.connected_members.map((c) => c.user_id) + console.time("getRtcState") + state.rtc = + (await ctx.mediaChannels.findChannelsByGroupId(group_id)) ?? [] + console.timeEnd("getRtcState") - return { - ...group, - channels: channels, + if (Array.isArray(state.rtc)) { + // map channel clients + state.rtc = state.rtc.map((channel) => { + return { + __v: channel.data.__v, + _id: channel.data._id, + clients: channel.getConnectedClientsSerialized(), + producers: channel.getProducersSerialized(), + started_at: channel.started_at, + } + }) } + + // get connected users + if (Array.isArray(state.memberships) && state.memberships.length > 0) { + state.connected_members = await UserConnections.isUsersConnected( + ctx.redis.client, + state.memberships.map((member) => member.user_id), + ) + + // filter & map connected users ids + state.connected_members = state.connected_members.filter( + (c) => c.connected, + ) + state.connected_members = state.connected_members.map( + (c) => c.user_id, + ) + } + + return state }, } diff --git a/packages/server/services/rtc/rtc.service.js b/packages/server/services/rtc/rtc.service.js index 71ec3aaf6..0b96dd5a9 100644 --- a/packages/server/services/rtc/rtc.service.js +++ b/packages/server/services/rtc/rtc.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import SharedMiddlewares from "@shared-middlewares" diff --git a/packages/server/services/rtc/utils/getAnnouncedIp.js b/packages/server/services/rtc/utils/getAnnouncedIp.js new file mode 100644 index 000000000..66b682c3c --- /dev/null +++ b/packages/server/services/rtc/utils/getAnnouncedIp.js @@ -0,0 +1,12 @@ +export default () => { + let announcedIp = process.env.MEDIASOUP_ANNOUNCED_IP + + if (!announcedIp) { + announcedIp = + process.env.NODE_ENV === "production" + ? clientIp || "127.0.0.1" + : "127.0.0.1" + } + + return announcedIp +} diff --git a/packages/server/services/rtc/ws_routes/call/leave.js b/packages/server/services/rtc/ws_routes/call/leave.js new file mode 100644 index 000000000..e8209e963 --- /dev/null +++ b/packages/server/services/rtc/ws_routes/call/leave.js @@ -0,0 +1,3 @@ +export default async (client, payload = {}) => { + return await global.userCalls.leave(client, payload) +} diff --git a/packages/server/services/rtc/ws_routes/channel/client_event.js b/packages/server/services/rtc/ws_routes/channel/client_event.js index 878e035a1..0f7afef28 100644 --- a/packages/server/services/rtc/ws_routes/channel/client_event.js +++ b/packages/server/services/rtc/ws_routes/channel/client_event.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/connect_transport.js b/packages/server/services/rtc/ws_routes/channel/connect_transport.js index bc1c1c87e..d62ea7b9e 100644 --- a/packages/server/services/rtc/ws_routes/channel/connect_transport.js +++ b/packages/server/services/rtc/ws_routes/channel/connect_transport.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/consume.js b/packages/server/services/rtc/ws_routes/channel/consume.js index b452b80ce..7c0e682f3 100644 --- a/packages/server/services/rtc/ws_routes/channel/consume.js +++ b/packages/server/services/rtc/ws_routes/channel/consume.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/create_transport.js b/packages/server/services/rtc/ws_routes/channel/create_transport.js index 7bf9fc5b2..6e7576dc2 100644 --- a/packages/server/services/rtc/ws_routes/channel/create_transport.js +++ b/packages/server/services/rtc/ws_routes/channel/create_transport.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/join.js b/packages/server/services/rtc/ws_routes/channel/join.js index 2bf8727d5..896f7bc74 100644 --- a/packages/server/services/rtc/ws_routes/channel/join.js +++ b/packages/server/services/rtc/ws_routes/channel/join.js @@ -1,3 +1,15 @@ export default async (client, media_channel_id) => { - return await global.mediaChannels.joinClient(client, media_channel_id) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } + + if (!channelInstance) { + throw new OperationError(404, "No channel available") + } + + return await channelInstance.joinClient(client) } diff --git a/packages/server/services/rtc/ws_routes/channel/leave.js b/packages/server/services/rtc/ws_routes/channel/leave.js index 56ce28782..44d589e17 100644 --- a/packages/server/services/rtc/ws_routes/channel/leave.js +++ b/packages/server/services/rtc/ws_routes/channel/leave.js @@ -1,3 +1,15 @@ -export default async (client) => { - return await global.mediaChannels.leaveClient(client) +export default async (client, payload = {}) => { + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } + + if (!channelInstance) { + throw new OperationError(404, "No channel available") + } + + return await channelInstance.leaveClient(client) } diff --git a/packages/server/services/rtc/ws_routes/channel/produce.js b/packages/server/services/rtc/ws_routes/channel/produce.js index 20e348288..7e9965656 100644 --- a/packages/server/services/rtc/ws_routes/channel/produce.js +++ b/packages/server/services/rtc/ws_routes/channel/produce.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/produce:stop.js b/packages/server/services/rtc/ws_routes/channel/produce:stop.js index 269e8260c..717020705 100644 --- a/packages/server/services/rtc/ws_routes/channel/produce:stop.js +++ b/packages/server/services/rtc/ws_routes/channel/produce:stop.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/rtc/ws_routes/channel/soundpad_dispatch.js b/packages/server/services/rtc/ws_routes/channel/soundpad_dispatch.js index c82924286..58e5886ad 100644 --- a/packages/server/services/rtc/ws_routes/channel/soundpad_dispatch.js +++ b/packages/server/services/rtc/ws_routes/channel/soundpad_dispatch.js @@ -1,5 +1,11 @@ export default async (client, payload) => { - const channelInstance = global.mediaChannels.getClientChannel(client) + let channelInstance = null + + if (payload.isDm === true) { + channelInstance = global.userCalls.getClientChannel(client) + } else { + channelInstance = global.mediaChannels.getClientChannel(client) + } if (!channelInstance) { throw new OperationError(404, "No channel available") diff --git a/packages/server/services/search/search.service.js b/packages/server/services/search/search.service.js index b8266f9a8..586253e2c 100644 --- a/packages/server/services/search/search.service.js +++ b/packages/server/services/search/search.service.js @@ -1,6 +1,6 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" diff --git a/packages/server/services/users/users.service.js b/packages/server/services/users/users.service.js index 63d5b7bf3..891598251 100644 --- a/packages/server/services/users/users.service.js +++ b/packages/server/services/users/users.service.js @@ -1,11 +1,10 @@ import { Server } from "linebridge" -import ScyllaDb from "@shared-classes/ScyllaDb" +import ScyllaDb from "@ragestudio/scylla-odm" import DbManager from "@shared-classes/DbManager" import RedisClient from "@shared-classes/RedisClient" import SharedMiddlewares from "@shared-middlewares" -import InjectedAuth from "@shared-lib/injectedAuth" export default class API extends Server { static refName = "users" diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index fcce3edcd..297032ea7 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -1,13 +1,23 @@ { + "$schema": "http://json.schemastore.org/tsconfig", "compilerOptions": { - "target": "ES2022", + "allowSyntheticDefaultImports": true, + "target": "ES2023", "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, "strict": false, "noImplicitAny": false, "skipLibCheck": true, "preserveConstEnums": true, "sourceMap": true, "baseUrl": ".", + "paths": { + "@shared-classes/*": ["./classes/*"], + "@db/*": ["db/*"], + }, }, "files": ["global.d.ts"], "include": ["**/*.ts", "types/**/*.d.ts"], diff --git a/packages/server/utils/readFileHash.js b/packages/server/utils/readFileHash.js index 5f6be7f81..a4fec0788 100644 --- a/packages/server/utils/readFileHash.js +++ b/packages/server/utils/readFileHash.js @@ -1,18 +1,16 @@ import fs from "node:fs" import crypto from "crypto" -export default async (file) => { - return new Promise((resolve, reject) => { - if (typeof file === "string") { - file = fs.createReadStream(file) - } +export default async (stream) => { + if (typeof stream === "string") { + stream = fs.createReadStream(stream) + } - const hash = crypto.createHash("sha256") + const hash = crypto.createHash("sha256") - file.on("data", (chunk) => hash.update(chunk)) + for await (const chunk of stream) { + hash.update(chunk) + } - file.on("end", () => resolve(hash.digest("hex"))) - - file.on("error", reject) - }) -} \ No newline at end of file + return hash.digest("hex") +} diff --git a/packages/server/vitest.config.ts b/packages/server/vitest.config.ts new file mode 100644 index 000000000..8ae6a7438 --- /dev/null +++ b/packages/server/vitest.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "vitest/config" +import path from "path" + +export default defineConfig({ + test: { + environment: "node", + globals: true, + setupFiles: [], + testTimeout: 30000, + coverage: { + provider: "v8", + reporter: ["text", "json", "html"], + include: ["**/*.{ts,js}"], + exclude: ["**/node_modules/**", "**/*.test.{ts,js}", "**/dist/**"], + }, + }, + resolve: { + alias: { + "^@shared-classes/Scylla$": path.resolve( + __dirname, + "classes/Scylla/index.ts", + ), + "^@shared-classes/Scylla/(.*)$": path.resolve( + __dirname, + "classes/Scylla/$1", + ), + }, + }, +})