diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 71376637a2..9c86cb8b04 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -14,6 +14,7 @@ on: - alpha - internal - testnet-three + - experiment jobs: publish: runs-on: ubuntu-latest diff --git a/Dockerfile.node b/Dockerfile.node index 2e3a36cca5..fcdedd6ace 100644 --- a/Dockerfile.node +++ b/Dockerfile.node @@ -3,8 +3,11 @@ FROM node:${NODE_VERSION}-bullseye AS build WORKDIR /usr/src/network COPY . . RUN --mount=type=cache,target=/root/.npm \ + npm run bootstrap-pkg --package=@streamr/utils && \ npm run bootstrap-pkg --package=@streamr/proto-rpc && \ npm run bootstrap-pkg --package=@streamr/autocertifier-client && \ + npm run bootstrap-pkg --package=@streamr/cdn-location && \ + npm run bootstrap-pkg --package=@streamr/geoip-location && \ npm run bootstrap-pkg --package=@streamr/dht && \ npm run bootstrap-pkg --package=@streamr/trackerless-network && \ npm run bootstrap-pkg --package=@streamr/sdk && \ diff --git a/docs/docs/help/operator-faq.md b/docs/docs/help/operator-faq.md index 3a7bbc98ad..7f0c82c343 100644 --- a/docs/docs/help/operator-faq.md +++ b/docs/docs/help/operator-faq.md @@ -179,10 +179,10 @@ Recheck operator address from the hub & reconfigure your node to use the correct I’m receiving the following warning message. ```JSON -WARN [2023-11-10T10:01:42.418] (NodeWebRtcConnection): Failed to set remote descriptor for peer 0a3849076d8a43b19b876fbc6eba935f -WARN [2023-11-10T10:01:42.421] (NodeWebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f -WARN [2023-11-10T10:01:42.622] (NodeWebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f -WARN [2023-11-10T10:01:42.867] (NodeWebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f +WARN [2023-11-10T10:01:42.418] (WebRtcConnection): Failed to set remote descriptor for peer 0a3849076d8a43b19b876fbc6eba935f +WARN [2023-11-10T10:01:42.421] (WebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f +WARN [2023-11-10T10:01:42.622] (WebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f +WARN [2023-11-10T10:01:42.867] (WebRtcConnection): Failed to set remote candidate for peer 0a3849076d8a43b19b876fbc6eba935f ``` **Explanation:** @@ -332,4 +332,4 @@ You'll need to pay the early exit fee of 5k DATA. The unwithdrawn earnings from #### What are some tips for staying safe on Streamr? - Consider starting small with your stake amount and use common sense to never stake more than you can afford to lose. A professional audit of the incentive layer has been completed by Cyfrin, but nothing can be guaranteed of course. - If you want to stake on a sponsorship, DO NOT click on the "Sponsor". That's for funding the sponsorship, not staking! Instead, go to the sponsorship you want to stake on and click "Join as an operator” and enter the amount. -- There may be an increase in activity by scammers. A common approach is to pretend to offer help or tech support in direct messages (something we never do). Report any account that is asking you to sign transactions or asking for any sort of credentials such as your private key. These accounts are trying to steal your tokens. It’s advised you disable DMs on Discord. More tips can be found in #server-safety-guide. \ No newline at end of file +- There may be an increase in activity by scammers. A common approach is to pretend to offer help or tech support in direct messages (something we never do). Report any account that is asking you to sign transactions or asking for any sort of credentials such as your private key. These accounts are trying to steal your tokens. It’s advised you disable DMs on Discord. More tips can be found in #server-safety-guide. diff --git a/package-lock.json b/package-lock.json index cb16735f4a..21de4d1001 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3035,622 +3035,764 @@ "tslib": "^2.4.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/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/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", - "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" + "node": ">=18" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz", - "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.11.0", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, "license": "MIT", - "optional": true + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "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/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": ">=18" } }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=18.18.0" + "node": ">=18" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", - "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@inquirer/ansi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", - "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { "node": ">=18" } }, - "node_modules/@inquirer/checkbox": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", - "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } } }, - "node_modules/@inquirer/confirm": { - "version": "5.1.19", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", - "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } } }, - "node_modules/@inquirer/core": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", - "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } } }, - "node_modules/@inquirer/editor": { - "version": "4.2.21", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", - "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/external-editor": "^1.0.2", - "@inquirer/type": "^3.0.9" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@types/node": ">=18" + "funding": { + "url": "https://opencollective.com/eslint" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@inquirer/expand": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", - "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, + "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" - }, - "peerDependencies": { - "@types/node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", - "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, "license": "MIT", - "dependencies": { - "chardet": "^2.1.0", - "iconv-lite": "^0.7.0" - }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@inquirer/figures": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", - "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@inquirer/input": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", - "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", - "license": "MIT", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "*" } }, - "node_modules/@inquirer/number": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", - "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", - "license": "MIT", + "node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@inquirer/password": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", - "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@inquirer/prompts": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz", - "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", "dependencies": { - "@inquirer/checkbox": "^4.3.0", - "@inquirer/confirm": "^5.1.19", - "@inquirer/editor": "^4.2.21", - "@inquirer/expand": "^4.0.21", - "@inquirer/input": "^4.2.5", - "@inquirer/number": "^3.0.21", - "@inquirer/password": "^4.0.21", - "@inquirer/rawlist": "^4.1.9", - "@inquirer/search": "^3.2.0", - "@inquirer/select": "^4.4.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@inquirer/rawlist": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", - "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@inquirer/search": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", - "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - }, "engines": { "node": ">=18" }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@inquirer/select": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", - "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz", + "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.11.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "license": "MIT", + "optional": true + }, + "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.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", + "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", "@inquirer/figures": "^1.0.14", "@inquirer/type": "^3.0.9", "yoctocolors-cjs": "^2.1.2" @@ -3667,15 +3809,14 @@ } } }, - "node_modules/@inquirer/testing": { - "version": "2.1.51", - "resolved": "https://registry.npmjs.org/@inquirer/testing/-/testing-2.1.51.tgz", - "integrity": "sha512-ZY1mp+AAxhwdJ+IzioKTPgxyqHWLGYZpOzQ3nkHJ8CMp+vpRtI5k94fktBbIXCsjNtOEm8SMttgLPKEK9si2nQ==", - "dev": true, + "node_modules/@inquirer/confirm": { + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", + "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", "license": "MIT", "dependencies": { - "@inquirer/type": "^3.0.9", - "mute-stream": "^2.0.0" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { "node": ">=18" @@ -3689,11 +3830,21 @@ } } }, - "node_modules/@inquirer/type": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", - "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "node_modules/@inquirer/core": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, "engines": { "node": ">=18" }, @@ -3706,202 +3857,493 @@ } } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, + "node_modules/@inquirer/editor": { + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", + "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/external-editor": "^1.0.2", + "@inquirer/type": "^3.0.9" + }, "engines": { - "node": "20 || >=22" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, + "node_modules/@inquirer/expand": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", + "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", "license": "MIT", "dependencies": { - "@isaacs/balanced-match": "^4.0.1" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" }, "engines": { - "node": "20 || >=22" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", - "license": "ISC", + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "license": "MIT", "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" + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">=12" + "node": ">=0.10.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "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==", - "license": "MIT" + "node_modules/@inquirer/figures": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", + "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, - "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==", + "node_modules/@inquirer/input": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", + "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/@inquirer/number": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", + "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/password": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", + "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", "license": "MIT", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" }, "engines": { - "node": ">=12" + "node": ">=18" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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", + "node_modules/@inquirer/prompts": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.9.0.tgz", + "integrity": "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==", + "license": "MIT", "dependencies": { - "minipass": "^7.0.4" + "@inquirer/checkbox": "^4.3.0", + "@inquirer/confirm": "^5.1.19", + "@inquirer/editor": "^4.2.21", + "@inquirer/expand": "^4.0.21", + "@inquirer/input": "^4.2.5", + "@inquirer/number": "^3.0.21", + "@inquirer/password": "^4.0.21", + "@inquirer/rawlist": "^4.1.9", + "@inquirer/search": "^3.2.0", + "@inquirer/select": "^4.4.0" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@isaacs/fs-minipass/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", - "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", - "dev": true, - "license": "ISC" - }, - "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==", - "license": "ISC", + "node_modules/@inquirer/rawlist": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", + "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", + "license": "MIT", "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" + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@inquirer/search": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", + "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", "license": "MIT", "dependencies": { - "sprintf-js": "~1.0.2" + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@inquirer/select": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", + "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/testing": { + "version": "2.1.51", + "resolved": "https://registry.npmjs.org/@inquirer/testing/-/testing-2.1.51.tgz", + "integrity": "sha512-ZY1mp+AAxhwdJ+IzioKTPgxyqHWLGYZpOzQ3nkHJ8CMp+vpRtI5k94fktBbIXCsjNtOEm8SMttgLPKEK9si2nQ==", + "dev": true, "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@inquirer/type": "^3.0.9", + "mute-stream": "^2.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "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==", + "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.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "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.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "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==", + "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==", + "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.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "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==", + "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/@isaacs/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "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==", + "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==", + "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": { @@ -4361,9 +4803,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -6720,137 +7162,601 @@ "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", "license": "MIT" }, - "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==", + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@protobuf-ts/plugin": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz", + "integrity": "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@bufbuild/protobuf": "^2.4.0", + "@bufbuild/protoplugin": "^2.4.0", + "@protobuf-ts/protoc": "^2.11.1", + "@protobuf-ts/runtime": "^2.11.1", + "@protobuf-ts/runtime-rpc": "^2.11.1", + "typescript": "^3.9" + }, + "bin": { + "protoc-gen-dump": "bin/protoc-gen-dump", + "protoc-gen-ts": "bin/protoc-gen-ts" + } + }, + "node_modules/@protobuf-ts/plugin/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@protobuf-ts/protoc": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.11.1.tgz", + "integrity": "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "protoc": "protoc.js" + } + }, + "node_modules/@protobuf-ts/runtime": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.1.tgz", + "integrity": "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==", + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@protobuf-ts/runtime-rpc": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.11.1.tgz", + "integrity": "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==", + "license": "Apache-2.0", + "dependencies": { + "@protobuf-ts/runtime": "^2.11.1" + } + }, + "node_modules/@rollup/plugin-alias": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-6.0.0.tgz", + "integrity": "sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "rollup": ">=4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-29.0.0.tgz", + "integrity": "sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", + "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "cpu": [ + "ppc64" + ], + "dev": true, "license": "MIT", "optional": true, - "engines": { - "node": ">=14" - } + "os": [ + "linux" + ] }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "cpu": [ + "riscv64" + ], + "dev": true, "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=12.22.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@pnpm/npm-conf": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", - "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] }, - "node_modules/@protobuf-ts/plugin": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz", - "integrity": "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@bufbuild/protobuf": "^2.4.0", - "@bufbuild/protoplugin": "^2.4.0", - "@protobuf-ts/protoc": "^2.11.1", - "@protobuf-ts/runtime": "^2.11.1", - "@protobuf-ts/runtime-rpc": "^2.11.1", - "typescript": "^3.9" - }, - "bin": { - "protoc-gen-dump": "bin/protoc-gen-dump", - "protoc-gen-ts": "bin/protoc-gen-ts" - } + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/@protobuf-ts/plugin/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@protobuf-ts/protoc": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.11.1.tgz", - "integrity": "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "Apache-2.0", - "bin": { - "protoc": "protoc.js" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@protobuf-ts/runtime": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.1.tgz", - "integrity": "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==", - "license": "(Apache-2.0 AND BSD-3-Clause)" + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@protobuf-ts/runtime-rpc": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.11.1.tgz", - "integrity": "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==", - "license": "Apache-2.0", - "dependencies": { - "@protobuf-ts/runtime": "^2.11.1" - } + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@rtsao/scc": { "version": "1.1.0", @@ -8056,6 +8962,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/md5": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.6.tgz", + "integrity": "sha512-WD69gNXtRBnpknfZcb4TRQ0XJQbUPZcai/Qdhmka3sxUR3Et8NrXoeAoknG/LghYHTf4ve795rInVYHBTQdNVA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/merge2": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.4.4.tgz", @@ -8141,19 +9054,19 @@ "license": "MIT" }, "node_modules/@types/readable-stream": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz", - "integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.23.tgz", + "integrity": "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==", "license": "MIT", "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" + "@types/node": "*" } }, - "node_modules/@types/readable-stream/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==", + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, "license": "MIT" }, "node_modules/@types/responselike": { @@ -10556,7 +11469,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, "license": "MIT", "dependencies": { "buffer-xor": "^1.0.3", @@ -10811,11 +11723,19 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, + "node_modules/buffer-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-shim/-/buffer-shim-1.0.1.tgz", + "integrity": "sha512-VG1oTE6Ecr9h/Gx3XOXue0F1vQaQlkBd3tGAzpL7Fsu+8f1Jbtk5ORPkrVLA/ADBTQ08bcPt3HanaZ7tUfJqMg==", + "license": "ISC", + "peerDependencies": { + "buffer": "^6.0.3" + } + }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, "license": "MIT" }, "node_modules/bufferutil": { @@ -11138,6 +12058,15 @@ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", "license": "MIT" }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -11251,7 +12180,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.4", @@ -11615,6 +12543,13 @@ "dev": true, "license": "ISC" }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", @@ -12155,7 +13090,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, "license": "MIT", "dependencies": { "cipher-base": "^1.0.1", @@ -12201,6 +13135,15 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, "node_modules/crypto-browserify": { "version": "3.12.1", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", @@ -13473,6 +14416,48 @@ "node": ">=0.12" } }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -13988,6 +14973,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -14136,7 +15128,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "license": "MIT", "dependencies": { "md5.js": "^1.3.4", @@ -15645,7 +16636,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.4", @@ -16398,6 +17388,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, "node_modules/is-bun-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", @@ -16607,6 +17603,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, "node_modules/is-nan": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", @@ -16696,6 +17699,16 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -19360,6 +20373,16 @@ "node": "20 || >=22" } }, + "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/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -19627,11 +20650,21 @@ "node": ">= 0.4" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, "license": "MIT", "dependencies": { "hash-base": "^3.0.0", @@ -22808,7 +23841,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, "license": "MIT" }, "node_modules/path-exists": { @@ -24352,7 +25384,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "license": "MIT", "dependencies": { "hash-base": "^3.0.0", @@ -24378,6 +25409,74 @@ "node": ">=8.0" } }, + "node_modules/rollup": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", + "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.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-dts": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.3.0.tgz", + "integrity": "sha512-d0UrqxYd8KyZ6i3M2Nx7WOMy708qsV/7fTHMHxCMCBOAe3V/U7OMPu5GkX8hC+cmkHhzGnfeYongl1IgiooddA==", + "dev": true, + "license": "LGPL-3.0-only", + "dependencies": { + "magic-string": "^0.30.21" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.27.1" + }, + "peerDependencies": { + "rollup": "^3.29.4 || ^4", + "typescript": "^4.5 || ^5.0" + } + }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -24883,7 +25982,6 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.1", @@ -27057,6 +28155,26 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/tsyringe": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", @@ -28793,7 +29911,93 @@ "node-forge": "^1.3.2" }, "devDependencies": { - "@types/node-forge": "^1.3.14" + "@rollup/plugin-node-resolve": "^16.0.3", + "@types/node-forge": "^1.3.14", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + } + }, + "packages/autocertifier-client/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/autocertifier-client/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/autocertifier-client/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/autocertifier-client/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/autocertifier-client/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/autocertifier-server": { @@ -28832,6 +30036,7 @@ "devDependencies": { "@electron/rebuild": "^4.0.1", "@jest/fake-timers": "^30.0.5", + "@rollup/plugin-node-resolve": "^16.0.3", "buffer": "^6.0.3", "electron": "^34.0.0", "expect": "^30.0.5", @@ -28845,20 +30050,191 @@ "karma-spec-reporter": "^0.0.36", "karma-webpack": "^5.0.1", "node-polyfill-webpack-plugin": "^4.1.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0", "webpack": "^5.103.0", "webpack-cli": "^6.0.1" } }, - "packages/cdn-location": { - "name": "@streamr/cdn-location", - "version": "103.2.0", - "license": "Apache-2.0", + "packages/browser-test-runner/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/browser-test-runner/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/browser-test-runner/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/browser-test-runner/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/browser-test-runner/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/cdn-location": { + "name": "@streamr/cdn-location", + "version": "103.2.0", + "license": "Apache-2.0", + "dependencies": { + "@streamr/utils": "103.2.0", + "haversine": "^1.1.1" + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@types/haversine": "^1.1.8", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + } + }, + "packages/cdn-location/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/cdn-location/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/cdn-location/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/cdn-location/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@streamr/utils": "103.2.0", - "haversine": "^1.1.1" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, - "devDependencies": { - "@types/haversine": "^1.1.8" + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/cdn-location/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/cli-tools": { @@ -28916,6 +30292,9 @@ "ws": "^8.18.3" }, "devDependencies": { + "@rollup/plugin-alias": "^6.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", "@streamr/test-utils": "103.2.0", "@types/heap": "^0.2.35", @@ -28925,14 +30304,35 @@ "@types/ws": "^8.18.1", "jest-leak-detector": "^27.3.1", "jest-matcher-utils": "^30.0.5", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", "ts-essentials": "^10.1.1", - "ts-node": "^10.9.2" + "tsx": "^4.21.0" }, "optionalDependencies": { "bufferutil": "^4.0.9", "utf-8-validate": "^6.0.5" } }, + "packages/dht/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/dht/node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -28942,6 +30342,69 @@ "node": ">= 10" } }, + "packages/dht/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/dht/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/dht/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/dht/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/geoip-location": { "name": "@streamr/geoip-location", "version": "103.2.0", @@ -28955,9 +30418,95 @@ "uuid": "^11.1.0" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", "@types/long-timeout": "^0.1.2", "@types/tar": "^6.1.11", - "express": "^5.2.0" + "express": "^5.2.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + } + }, + "packages/geoip-location/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/geoip-location/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/geoip-location/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/geoip-location/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/geoip-location/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/node": { @@ -29023,32 +30572,118 @@ "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/proto-rpc": { + "name": "@streamr/proto-rpc", + "version": "103.2.0", + "license": "(Apache-2.0 AND BSD-3-Clause)", + "dependencies": { + "@protobuf-ts/runtime": "^2.8.2", + "@protobuf-ts/runtime-rpc": "^2.8.2", + "@streamr/utils": "103.2.0", + "eventemitter3": "^5.0.0", + "lodash": "^4.17.21", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@streamr/browser-test-runner": "^0.0.1", + "@streamr/test-utils": "103.2.0", + "@types/lodash": "^4.17.21", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + }, + "optionalDependencies": { + "bufferutil": "^4.0.9", + "utf-8-validate": "^6.0.5" + } + }, + "packages/proto-rpc/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/proto-rpc/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/proto-rpc/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/proto-rpc/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "packages/proto-rpc": { - "name": "@streamr/proto-rpc", - "version": "103.2.0", - "license": "(Apache-2.0 AND BSD-3-Clause)", + "packages/proto-rpc/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@protobuf-ts/runtime": "^2.8.2", - "@protobuf-ts/runtime-rpc": "^2.8.2", - "@streamr/utils": "103.2.0", - "eventemitter3": "^5.0.0", - "lodash": "^4.17.21", - "uuid": "^11.1.0" + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" }, - "devDependencies": { - "@streamr/browser-test-runner": "^0.0.1", - "@streamr/test-utils": "103.2.0", - "@types/lodash": "^4.17.21" + "bin": { + "rimraf": "dist/esm/bin.mjs" }, - "optionalDependencies": { - "bufferutil": "^4.0.9", - "utf-8-validate": "^6.0.5" + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/sdk": { @@ -29160,8 +30795,94 @@ "lodash": "^4.17.21" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", "@types/cors": "^2.8.19", - "@types/express": "^5.0.1" + "@types/express": "^5.0.1", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + } + }, + "packages/test-utils/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/test-utils/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/test-utils/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/test-utils/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/test-utils/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/trackerless-network": { @@ -29181,12 +30902,99 @@ "yallist": "^5.0.0" }, "devDependencies": { + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", "@streamr/test-utils": "103.2.0", "@types/lodash": "^4.17.21", "@types/yallist": "^5.0.0", "expect": "^30.0.5", - "ts-node": "^10.9.2" + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "ts-node": "^10.9.2", + "tsx": "^4.21.0" + } + }, + "packages/trackerless-network/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/trackerless-network/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/trackerless-network/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/trackerless-network/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/trackerless-network/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "packages/trackerless-network/node_modules/yallist": { @@ -29204,18 +31012,129 @@ "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.9.7", + "@noble/hashes": "^2.0.1", "@noble/post-quantum": "^0.4.1", + "browserify-aes": "^1.2.0", + "buffer": "^6.0.3", + "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", + "md5": "^2.3.0", + "md5.js": "^1.3.5", + "path-browserify": "^1.0.1", "pino": "^10.1.0", "pino-pretty": "^13.1.2", + "readable-stream": "^4.7.0", "secp256k1": "^5.0.1", "sha3": "^2.1.4" }, "devDependencies": { + "@rollup/plugin-alias": "^6.0.0", + "@rollup/plugin-commonjs": "^29.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", "@types/lodash": "^4.17.21", - "@types/secp256k1": "^4.0.7" + "@types/md5": "^2.3.6", + "@types/readable-stream": "^4.0.23", + "@types/secp256k1": "^4.0.7", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" + } + }, + "packages/utils/node_modules/@noble/hashes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", + "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "packages/utils/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/utils/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/utils/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/utils/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/utils/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } } } diff --git a/packages/autocertifier-client/package.json b/packages/autocertifier-client/package.json index 6fbebb0aee..eecca476aa 100644 --- a/packages/autocertifier-client/package.json +++ b/packages/autocertifier-client/package.json @@ -1,34 +1,57 @@ { "name": "@streamr/autocertifier-client", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Autocertifier Client for Streamr Network", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/autocertifier-client" }, - "main": "dist/src/exports.js", - "types": "dist/src/exports.d.ts", + "main": "./dist/exports-nodejs.cjs", + "module": "./dist/exports-nodejs.js", + "types": "./dist/exports-nodejs.d.ts", + "exports": { + ".": { + "types": "./dist/exports-nodejs.d.ts", + "browser": { + "types": "./dist/exports-browser.d.ts", + "import": "./dist/exports-browser.js", + "require": "./dist/exports-browser.cjs" + }, + "node": "./dist/exports-nodejs.cjs", + "import": "./dist/exports-nodejs.js", + "require": "./dist/exports-nodejs.cjs", + "default": "./dist/exports-nodejs.js" + } + }, "files": [ - "dist", + "dist/exports-nodejs.*", + "dist/exports-browser.*", "!*.tsbuildinfo" ], "license": "STREAMR NETWORK OPEN SOURCE LICENSE", "author": "Streamr Network AG ", "scripts": { - "prebuild": "./proto.sh", + "prebuild": "npm run reset-self && ./proto.sh", "build": "tsc -b", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc --noEmit", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "rm -rf dist generated *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'" }, "dependencies": { "@protobuf-ts/runtime-rpc": "^2.8.2", - "@streamr/utils": "103.2.0", + "@streamr/utils": "103.2.0-experiment.1", "eventemitter3": "^5.0.0", "node-forge": "^1.3.2" }, "devDependencies": { - "@types/node-forge": "^1.3.14" + "@rollup/plugin-node-resolve": "^16.0.3", + "@types/node-forge": "^1.3.14", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" } } diff --git a/packages/autocertifier-client/rollup.config.mts b/packages/autocertifier-client/rollup.config.mts new file mode 100644 index 0000000000..12ffd4670e --- /dev/null +++ b/packages/autocertifier-client/rollup.config.mts @@ -0,0 +1,106 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + nodejs(), + nodejsTypes(), + browser(), + browserTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-nodejs.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-nodejs.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { + file: './dist/exports-nodejs.d.ts', + }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browser(): RollupOptions { + return { + input: './dist/src/exports-browser.js', + output: [ + { + format: 'es', + file: './dist/exports-browser.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-browser.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: false, + browser: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browserTypes(): RollupOptions { + return { + input: './dist/src/exports-browser.d.ts', + output: [ + { + file: './dist/exports-browser.d.ts', + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: false, + browser: true, + }), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/autocertifier-client/src/AutoCertifierClient.ts b/packages/autocertifier-client/src/AutoCertifierClient.ts index 56e9b9b127..87fd22817b 100644 --- a/packages/autocertifier-client/src/AutoCertifierClient.ts +++ b/packages/autocertifier-client/src/AutoCertifierClient.ts @@ -8,6 +8,7 @@ import { CertifiedSubdomain } from './data/CertifiedSubdomain' import fs from 'fs' import path from 'path' import * as forge from 'node-forge' +import { SERVICE_ID } from './consts' interface AutoCertifierClientEvents { updatedCertificate: (domain: CertifiedSubdomain) => void @@ -35,7 +36,6 @@ const getBaseDirectory = (directory: string): string => { return path.sep } -export const SERVICE_ID = 'system/auto-certificer' const ONE_DAY = 1000 * 60 * 60 * 24 const MAX_INT_32 = 2147483647 diff --git a/packages/autocertifier-client/src/consts.ts b/packages/autocertifier-client/src/consts.ts new file mode 100644 index 0000000000..fc7da60ba7 --- /dev/null +++ b/packages/autocertifier-client/src/consts.ts @@ -0,0 +1 @@ +export const SERVICE_ID = 'system/auto-certificer' diff --git a/packages/autocertifier-client/src/exports-browser.ts b/packages/autocertifier-client/src/exports-browser.ts new file mode 100644 index 0000000000..5fdf5e3905 --- /dev/null +++ b/packages/autocertifier-client/src/exports-browser.ts @@ -0,0 +1,3 @@ +export { SERVICE_ID } from './consts' +export type { CertifiedSubdomain } from './data/CertifiedSubdomain' +export type { AutoCertifierClient } from './AutoCertifierClient' diff --git a/packages/autocertifier-client/src/exports.ts b/packages/autocertifier-client/src/exports.ts index 1dfbe9542b..aef9ce6e35 100644 --- a/packages/autocertifier-client/src/exports.ts +++ b/packages/autocertifier-client/src/exports.ts @@ -1,4 +1,5 @@ -export { AutoCertifierClient, SERVICE_ID, type HasSession } from './AutoCertifierClient' +export { AutoCertifierClient, type HasSession } from './AutoCertifierClient' +export { SERVICE_ID } from './consts' export type { CertifiedSubdomain } from './data/CertifiedSubdomain' export type { Session } from './data/Session' export type { UpdateIpAndPortRequest } from './data/UpdateIpAndPortRequest' diff --git a/packages/autocertifier-client/tsconfig.json b/packages/autocertifier-client/tsconfig.json index 9bb9cf3b51..be7119ed21 100644 --- a/packages/autocertifier-client/tsconfig.json +++ b/packages/autocertifier-client/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." }, "include": [ "src" diff --git a/packages/autocertifier-server/package.json b/packages/autocertifier-server/package.json index 85079ac178..afbc24fe84 100644 --- a/packages/autocertifier-server/package.json +++ b/packages/autocertifier-server/package.json @@ -1,6 +1,6 @@ { "name": "@streamr/autocertifier-server", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Server for providing TLS Certificates", "repository": { "type": "git", @@ -34,10 +34,10 @@ }, "dependencies": { "@aws-sdk/client-route-53": "^3.936.0", - "@streamr/autocertifier-client": "103.2.0", - "@streamr/dht": "103.2.0", - "@streamr/proto-rpc": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/autocertifier-client": "103.2.0-experiment.1", + "@streamr/dht": "103.2.0-experiment.1", + "@streamr/proto-rpc": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "acme-client": "^5.4.0", "body-parser": "^2.2.1", "dns2": "^2.1.0", diff --git a/packages/browser-test-runner/package.json b/packages/browser-test-runner/package.json index bdf09514a4..5dee6d7307 100644 --- a/packages/browser-test-runner/package.json +++ b/packages/browser-test-runner/package.json @@ -8,18 +8,24 @@ "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/browser-test-runner" }, - "main": "./dist/src/exports.js", - "browser": { - "./dist/src/exports.js": false - }, + "main": "./dist/exports.cjs", + "module": "./dist/exports.js", + "types": "./dist/exports.d.ts", "files": [ - "dist", + "dist/exports.*", + "dist/preload.cjs", + "dist/preload.cjs.map", + "dist/karma-setup.js", + "dist/karma-setup.js.map", "!*.tsbuildinfo", "LICENSE" ], "scripts": { + "prebuild": "npm run reset-self", "build": "tsc -b", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc --noEmit", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '**/*.{js,ts}'" }, "author": "Streamr Network AG ", @@ -27,6 +33,7 @@ "devDependencies": { "@electron/rebuild": "^4.0.1", "@jest/fake-timers": "^30.0.5", + "@rollup/plugin-node-resolve": "^16.0.3", "buffer": "^6.0.3", "electron": "^34.0.0", "expect": "^30.0.5", @@ -40,6 +47,10 @@ "karma-spec-reporter": "^0.0.36", "karma-webpack": "^5.0.1", "node-polyfill-webpack-plugin": "^4.1.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0", "webpack": "^5.103.0", "webpack-cli": "^6.0.1" } diff --git a/packages/browser-test-runner/rollup.config.mts b/packages/browser-test-runner/rollup.config.mts new file mode 100644 index 0000000000..394651dd05 --- /dev/null +++ b/packages/browser-test-runner/rollup.config.mts @@ -0,0 +1,95 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + ...nodejs(), + nodejsTypes(), +]) + +function nodejs(): RollupOptions[] { + return [ + { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + }, + { + /** + * We need a CJS preload file for Electron apps - that's the only format they support. + */ + input: './dist/src/preload.js', + output: [ + { + format: 'cjs', + file: './dist/preload.cjs', + sourcemap: true, + }, + ], + external: [ + /node_modules/, + /@streamr\//, + ], + }, + { + /** + * For Karma test runner. We only need ES module format here. + */ + input: './dist/src/karma-setup.js', + output: [ + { + format: 'es', + file: './dist/karma-setup.js', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + }, + ] +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { + file: './dist/exports.d.ts', + }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/browser-test-runner/src/createKarmaConfig.ts b/packages/browser-test-runner/src/createKarmaConfig.ts index 38d09d8285..dd169dd8cf 100644 --- a/packages/browser-test-runner/src/createKarmaConfig.ts +++ b/packages/browser-test-runner/src/createKarmaConfig.ts @@ -1,4 +1,5 @@ import fs from 'fs' +import { fileURLToPath } from 'url' import type { Configuration, ExternalItem } from 'webpack' const DEBUG_MODE = process.env.BROWSER_TEST_DEBUG_MODE ?? false @@ -6,7 +7,7 @@ const DEBUG_MODE = process.env.BROWSER_TEST_DEBUG_MODE ?? false export const createKarmaConfig = ( testPaths: string[], webpackConfig: () => Configuration, localDirectory?: string ): (config: any) => any => { - const setupFiles = [__dirname + '/karma-setup.js'] + const setupFiles = [fileURLToPath(new URL('./karma-setup.js', import.meta.url))] if (localDirectory !== undefined) { const localSetupFile = localDirectory + '/karma-setup.js' @@ -58,7 +59,7 @@ export const createKarmaConfig = ( browserWindowOptions: { webPreferences: { contextIsolation: false, - preload: __dirname + '/preload.js', + preload: fileURLToPath(new URL('./preload.cjs', import.meta.url)), webSecurity: false, sandbox: false, nodeIntegration: true diff --git a/packages/browser-test-runner/src/createWebpackConfig.ts b/packages/browser-test-runner/src/createWebpackConfig.ts index 293d89f9d6..c779946dd6 100644 --- a/packages/browser-test-runner/src/createWebpackConfig.ts +++ b/packages/browser-test-runner/src/createWebpackConfig.ts @@ -44,7 +44,10 @@ export const createWebpackConfig = ( resolve: { extensions: ['.ts', '.js'], alias, - fallback, + fallback: { + timers: false, + ...fallback + }, }, output: { sourceMapFilename: `[name].[contenthash].js.map`, diff --git a/packages/browser-test-runner/src/karma-setup.js b/packages/browser-test-runner/src/karma-setup.js index ad535f344a..e31ed48ce2 100644 --- a/packages/browser-test-runner/src/karma-setup.js +++ b/packages/browser-test-runner/src/karma-setup.js @@ -3,7 +3,7 @@ import * as jestMock from 'jest-mock' -const expect = require('expect').default +import expect from 'expect' import { ModernFakeTimers } from '@jest/fake-timers' diff --git a/packages/browser-test-runner/tsconfig.json b/packages/browser-test-runner/tsconfig.json index 126cae2a06..9544356da2 100644 --- a/packages/browser-test-runner/tsconfig.json +++ b/packages/browser-test-runner/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." }, "include": [ "src" diff --git a/packages/cdn-location/package.json b/packages/cdn-location/package.json index e23265e26c..bef3ad37eb 100644 --- a/packages/cdn-location/package.json +++ b/packages/cdn-location/package.json @@ -1,16 +1,17 @@ { "name": "@streamr/cdn-location", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Library for getting own approximate location by querying CDN servers", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/cdn-location" }, - "main": "dist/src/exports.js", - "types": "dist/src/exports.d.ts", + "main": "./dist/exports.cjs", + "module": "./dist/exports.js", + "types": "./dist/exports.d.ts", "files": [ - "dist", + "dist/exports.*", "!*.tsbuildinfo", "README.md", "LICENSE" @@ -18,8 +19,11 @@ "license": "Apache-2.0", "author": "Streamr Network AG ", "scripts": { + "prebuild": "npm run reset-self", "build": "tsc -b", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -p tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", "test": "jest test/integration", @@ -28,10 +32,15 @@ "generate-data-from-tsp-solution": "./data-generation/generateDataFromTSPSolverResult.sh" }, "dependencies": { - "@streamr/utils": "103.2.0", + "@streamr/utils": "103.2.0-experiment.1", "haversine": "^1.1.1" }, "devDependencies": { - "@types/haversine": "^1.1.8" + "@rollup/plugin-node-resolve": "^16.0.3", + "@types/haversine": "^1.1.8", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" } } diff --git a/packages/cdn-location/rollup.config.mts b/packages/cdn-location/rollup.config.mts new file mode 100644 index 0000000000..cc1fbda131 --- /dev/null +++ b/packages/cdn-location/rollup.config.mts @@ -0,0 +1,54 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + nodejs(), + nodejsTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { + file: './dist/exports.d.ts', + }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/cdn-location/tsconfig.json b/packages/cdn-location/tsconfig.json index 5621ed82fc..6ad637ddb1 100644 --- a/packages/cdn-location/tsconfig.json +++ b/packages/cdn-location/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." }, "include": [ "src" diff --git a/packages/cli-tools/package.json b/packages/cli-tools/package.json index 68407cecff..e7a798bb5c 100644 --- a/packages/cli-tools/package.json +++ b/packages/cli-tools/package.json @@ -1,6 +1,6 @@ { "name": "@streamr/cli-tools", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Command line tools for Streamr", "repository": { "type": "git", @@ -33,11 +33,11 @@ "license": "AGPL-3.0", "dependencies": { "@streamr/config": "^5.9.2", - "@streamr/dht": "103.2.0", + "@streamr/dht": "103.2.0-experiment.1", "@streamr/network-contracts": "^9.1.0", - "@streamr/sdk": "103.2.0", - "@streamr/trackerless-network": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/sdk": "103.2.0-experiment.1", + "@streamr/trackerless-network": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "commander": "^14.0.2", "easy-table": "^1.1.1", "ethers": "^6.13.0", @@ -46,7 +46,7 @@ "semver": "^7.7.3" }, "devDependencies": { - "@streamr/test-utils": "103.2.0", + "@streamr/test-utils": "103.2.0-experiment.1", "@types/event-stream": "^4.0.6", "@types/lodash": "^4.17.21", "@types/merge2": "^1.4.4", diff --git a/packages/dht/jest.config.ts b/packages/dht/jest.config.ts index 829ec460e5..330629096c 100644 --- a/packages/dht/jest.config.ts +++ b/packages/dht/jest.config.ts @@ -3,6 +3,9 @@ import defaultConfig from '../../jest.config' const config: Config.InitialOptions = { ...defaultConfig, + moduleNameMapper: { + '^@/(.*)$': '/src/nodejs/$1' + }, setupFilesAfterEnv: [ ...defaultConfig.setupFilesAfterEnv, './test/utils/customMatchers.ts', diff --git a/packages/dht/karma.config.ts b/packages/dht/karma.config.ts index 505d61e569..a304099ecc 100644 --- a/packages/dht/karma.config.ts +++ b/packages/dht/karma.config.ts @@ -7,18 +7,28 @@ const TEST_PATHS = [ './test/end-to-end/**/!(RecoveryFromFailedAutoCertification*|memory-leak*|GeoIpLayer0*).ts' ] -const NodeWebrtcConnection = resolve(__dirname, 'src/connection/webrtc/NodeWebrtcConnection.ts') -const BrowserWebrtcConnection = resolve(__dirname, 'src/connection/webrtc/BrowserWebrtcConnection.ts') -const NodeWebsocketClientConnection = resolve(__dirname, 'src/connection/websocket/NodeWebsocketClientConnection.ts') -const BrowserWebsocketClientConnection = resolve(__dirname, 'src/connection/websocket/BrowserWebsocketClientConnection.ts') - export default createKarmaConfig( TEST_PATHS, createWebpackConfig({ libraryName: 'dht', alias: { - [NodeWebrtcConnection]: BrowserWebrtcConnection, - [NodeWebsocketClientConnection]: BrowserWebsocketClientConnection + /** + * Our "browser" tests use the Node.js build of `autocertifier-client` package – needed + * for certifications stuff, but still, very confusing. + */ + '@streamr/autocertifier-client': resolve(__dirname, '../autocertifier-client/dist/exports-nodejs.cjs'), + + /** + * Selectively alias only browser-specific implementations here. The rest stays in `nodejs/` + * because these (like WebsocketServer) are needed for testing and running WebSocket-based + * code in Electron environment. + * + * This also proves that the "browser" test are really nodejs-flavoured browser tests where + * we still depend on NodeJS elements. + */ + '@/WebrtcConnection': resolve(__dirname, 'src/browser/WebrtcConnection.ts'), + '@/WebsocketClientConnection': resolve(__dirname, 'src/browser/WebsocketClientConnection.ts'), + '@': resolve(__dirname, 'src/nodejs'), }, fallback: { module: false diff --git a/packages/dht/package.json b/packages/dht/package.json index eac24b4a71..1abf88468a 100644 --- a/packages/dht/package.json +++ b/packages/dht/package.json @@ -1,32 +1,43 @@ { "name": "@streamr/dht", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Streamr Network DHT", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/dht" }, - "main": "./dist/src/exports.js", - "types": "./dist/src/exports.d.ts", - "browser": { - "./dist/src/connection/webrtc/NodeWebrtcConnection.js": "./dist/src/connection/webrtc/BrowserWebrtcConnection.js", - "./dist/src/connection/websocket/NodeWebsocketClientConnection.js": "./dist/src/connection/websocket/BrowserWebsocketClientConnection.js", - "./dist/src/helpers/browser/isBrowserEnvironment.js": "./dist/src/helpers/browser/isBrowserEnvironment_override.js" + "main": "./dist/exports-nodejs.cjs", + "module": "./dist/exports-nodejs.js", + "types": "./dist/exports-nodejs.d.ts", + "exports": { + ".": { + "types": "./dist/exports-nodejs.d.ts", + "browser": { + "types": "./dist/exports-browser.d.ts", + "import": "./dist/exports-browser.js", + "require": "./dist/exports-browser.cjs" + }, + "node": "./dist/exports-nodejs.cjs", + "import": "./dist/exports-nodejs.js", + "require": "./dist/exports-nodejs.cjs", + "default": "./dist/exports-nodejs.js" + } }, - "license": "STREAMR NETWORK OPEN SOURCE LICENSE", - "author": "Streamr Network AG ", "files": [ - "dist", + "dist/exports-nodejs.*", + "dist/exports-browser.*", "!*.tsbuildinfo", "README.md" ], + "license": "STREAMR NETWORK OPEN SOURCE LICENSE", + "author": "Streamr Network AG ", "scripts": { - "prebuild": "./proto.sh", - "postbuild": "./scripts/postbuild.sh", + "prebuild": "npm run reset-self && ./proto.sh", "build": "tsc -b", - "build-browser": "webpack --mode=development --progress", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -b tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist generated *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", "test": "npm run test-unit && npm run test-integration && npm run test-end-to-end", @@ -40,11 +51,11 @@ "@js-sdsl/ordered-map": "^4.4.2", "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", - "@streamr/autocertifier-client": "103.2.0", - "@streamr/cdn-location": "103.2.0", - "@streamr/geoip-location": "103.2.0", - "@streamr/proto-rpc": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/autocertifier-client": "103.2.0-experiment.1", + "@streamr/cdn-location": "103.2.0-experiment.1", + "@streamr/geoip-location": "103.2.0-experiment.1", + "@streamr/proto-rpc": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "eventemitter3": "^5.0.0", "heap": "^0.2.6", "ipaddr.js": "^2.0.1", @@ -57,8 +68,11 @@ "ws": "^8.18.3" }, "devDependencies": { + "@rollup/plugin-alias": "^6.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", - "@streamr/test-utils": "103.2.0", + "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/k-bucket": "^5.0.1", "@types/lodash": "^4.17.21", @@ -66,8 +80,11 @@ "@types/ws": "^8.18.1", "jest-leak-detector": "^27.3.1", "jest-matcher-utils": "^30.0.5", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", "ts-essentials": "^10.1.1", - "ts-node": "^10.9.2" + "tsx": "^4.21.0" }, "optionalDependencies": { "bufferutil": "^4.0.9", diff --git a/packages/dht/rollup.config.mts b/packages/dht/rollup.config.mts new file mode 100644 index 0000000000..e517ff650a --- /dev/null +++ b/packages/dht/rollup.config.mts @@ -0,0 +1,141 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import alias, { type Alias } from '@rollup/plugin-alias' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import json from '@rollup/plugin-json' +import { fileURLToPath } from 'url' + +const nodejsAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/nodejs/src/nodejs/', import.meta.url) + ), + }, +] + +const browserAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/browser/src/browser/', import.meta.url) + ), + }, +] + +export default defineConfig([ + nodejs(), + nodejsTypes(), + browser(), + browserTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/nodejs/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-nodejs.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-nodejs.cjs', + sourcemap: true, + }, + ], + plugins: [ + json(), + alias({ + entries: nodejsAliases, + }), + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/nodejs/src/exports.d.ts', + output: [ + { + file: './dist/exports-nodejs.d.ts', + }, + ], + plugins: [ + alias({ + entries: nodejsAliases, + }), + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + + } +} + +function browser(): RollupOptions { + return { + input: './dist/browser/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-browser.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-browser.cjs', + sourcemap: true, + }, + ], + plugins: [ + json(), + alias({ + entries: browserAliases, + }), + nodeResolve({ + preferBuiltins: false, + browser: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browserTypes(): RollupOptions { + return { + input: './dist/browser/src/exports.d.ts', + output: [ + { file: './dist/exports-browser.d.ts' }, + ], + plugins: [ + alias({ + entries: browserAliases, + }), + nodeResolve({ + preferBuiltins: false, + browser: true, + }), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/dht/scripts/postbuild.sh b/packages/dht/scripts/postbuild.sh deleted file mode 100755 index 70efe8acad..0000000000 --- a/packages/dht/scripts/postbuild.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -mkdir -p dist - -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -cd "${SCRIPT_DIR}/.." - -# Sanitize the final package.json -npx ts-node scripts/rewrite-package.ts diff --git a/packages/dht/scripts/rewrite-package.ts b/packages/dht/scripts/rewrite-package.ts deleted file mode 100644 index 9069678779..0000000000 --- a/packages/dht/scripts/rewrite-package.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * This script overwrites the package.json file inside the dist folder while - * adjusting relative pathnames for exports. Since the compiled output is inside - * "dist", but the original package.json references paths as if it's in the root, - * we need to strip "dist" from all export fields (main, types, …). - * - * This ensures that consumers of the package (incl. bundlers like Webpack) import - * the correct files without referencing "dist" in their paths, maintaining proper - * module resolution. - */ - -import pkg from '../package.json' -import * as fs from 'node:fs' -import path from 'node:path' - -function fixPathname(pathname: string): string { - return pathname.startsWith('./dist') - ? `./${path.relative('./dist', pathname)}` - : pathname -} - -const { main, types, browser, scripts: _scripts, ...rest } = pkg - -const newPkg = { - ...rest, - main: fixPathname(main), - types: fixPathname(types), - browser: Object.entries(browser).reduce( - (memo, [fromPathname, toPathname]) => ({ - ...memo, - [fixPathname(fromPathname)]: - typeof toPathname === 'string' - ? fixPathname(toPathname) - : toPathname, - }), - {} - ), -} - -const dist = path.resolve(__dirname, '../dist/package.json') - -fs.writeFileSync(dist, JSON.stringify(newPkg, null, 2)) diff --git a/packages/dht/scripts/tsconfig.json b/packages/dht/scripts/tsconfig.json deleted file mode 100644 index 5a03dbdeb8..0000000000 --- a/packages/dht/scripts/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "..", - "include": [ - "**/*" - ] -} diff --git a/packages/dht/src/connection/webrtc/BrowserWebrtcConnection.ts b/packages/dht/src/browser/WebrtcConnection.ts similarity index 92% rename from packages/dht/src/connection/webrtc/BrowserWebrtcConnection.ts rename to packages/dht/src/browser/WebrtcConnection.ts index 956fadc3cb..d4cb5a0acf 100644 --- a/packages/dht/src/connection/webrtc/BrowserWebrtcConnection.ts +++ b/packages/dht/src/browser/WebrtcConnection.ts @@ -1,11 +1,11 @@ -/// - -import EventEmitter from 'eventemitter3' -import { WebrtcConnectionEvents, IWebrtcConnection, RtcDescription } from './IWebrtcConnection' -import { IConnection, ConnectionID, ConnectionType } from '../IConnection' +import { EventEmitter } from 'eventemitter3' +import { WebrtcConnectionEvents, IWebrtcConnection, RtcDescription } from '../connection/webrtc/IWebrtcConnection' +import { IConnection, ConnectionID, ConnectionType } from '../connection/IConnection' import { Logger } from '@streamr/utils' -import { EARLY_TIMEOUT, IceServer } from './WebrtcConnector' -import { createRandomConnectionId } from '../Connection' +import { IceServer } from '../connection/webrtc/types' +import { EARLY_TIMEOUT } from '../connection/webrtc/consts' +import { createRandomConnectionId } from '../connection/Connection' +import type { WebrtcConnectionParams } from '../types/WebrtcConnectionParams' enum DisconnectedRtcPeerConnectionStateEnum { DISCONNECTED = 'disconnected', @@ -13,13 +13,9 @@ enum DisconnectedRtcPeerConnectionStateEnum { CLOSED = 'closed', } -const logger = new Logger('BrowserWebrtcConnection') - -interface Params { - iceServers?: IceServer[] -} +const logger = new Logger('WebrtcConnection (browser)') -export class NodeWebrtcConnection extends EventEmitter implements IWebrtcConnection, IConnection { +export class WebrtcConnection extends EventEmitter implements IWebrtcConnection, IConnection { public connectionId: ConnectionID public readonly connectionType: ConnectionType = ConnectionType.WEBRTC @@ -37,7 +33,7 @@ export class NodeWebrtcConnection extends EventEmitter i private earlyTimeout: NodeJS.Timeout private readonly messageQueue: Uint8Array[] = [] - constructor(params: Params) { + constructor(params: WebrtcConnectionParams) { super() this.connectionId = createRandomConnectionId() this.iceServers = params.iceServers ?? [] diff --git a/packages/dht/src/connection/websocket/BrowserWebsocketClientConnection.ts b/packages/dht/src/browser/WebsocketClientConnection.ts similarity index 90% rename from packages/dht/src/connection/websocket/BrowserWebsocketClientConnection.ts rename to packages/dht/src/browser/WebsocketClientConnection.ts index 4b0f01acb9..b0569991f9 100644 --- a/packages/dht/src/connection/websocket/BrowserWebsocketClientConnection.ts +++ b/packages/dht/src/browser/WebsocketClientConnection.ts @@ -1,8 +1,8 @@ import { Logger } from '@streamr/utils' import { ICloseEvent, IMessageEvent, w3cwebsocket as Websocket } from 'websocket' -import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection' +import { AbstractWebsocketClientConnection } from '../connection/websocket/AbstractWebsocketClientConnection' -const logger = new Logger('BrowserWebsocketClientConnection') +const logger = new Logger('WebsocketClientConnection (browser)') const BINARY_TYPE = 'arraybuffer' diff --git a/packages/dht/src/browser/WebsocketServer.ts b/packages/dht/src/browser/WebsocketServer.ts new file mode 100644 index 0000000000..3737e9f805 --- /dev/null +++ b/packages/dht/src/browser/WebsocketServer.ts @@ -0,0 +1,29 @@ +/* eslint-disable class-methods-use-this */ +import { EventEmitter } from 'eventemitter3' +import type { + IWebsocketServer, + WebsocketServerEvents, +} from '../connection/websocket/types' + +/** + * A stub WebsocketServer for browser environment. + */ + +export class WebsocketServer extends EventEmitter implements IWebsocketServer { + constructor(_params: unknown) { + super() + } + + public async start(): Promise { + throw new Error('WebsocketServer is not supported in browser environment') + } + + public async stop(): Promise { + throw new Error('WebsocketServer is not supported in browser environment') + } + + public updateCertificate(_cert: string, _key: string): void { + throw new Error('WebsocketServer is not supported in browser environment') + } +} + diff --git a/packages/dht/src/browser/createDefaultAutocertifierClient.ts b/packages/dht/src/browser/createDefaultAutocertifierClient.ts new file mode 100644 index 0000000000..c35a20c620 --- /dev/null +++ b/packages/dht/src/browser/createDefaultAutocertifierClient.ts @@ -0,0 +1,13 @@ +import type { AutoCertifierClient } from '@streamr/autocertifier-client' +import { ListeningRpcCommunicator } from '../transport/ListeningRpcCommunicator' + +export const createDefaultAutocertifierClient = ( + _configFile: string, + _autoCertifierUrl: string, + _autoCertifierRpcCommunicator: ListeningRpcCommunicator, + _wsServerPort: number +): AutoCertifierClient => { + throw new Error( + 'AutoCertifierClient is not supported in browser environment' + ) +} diff --git a/packages/dht/src/browser/createGeoipLocator.ts b/packages/dht/src/browser/createGeoipLocator.ts new file mode 100644 index 0000000000..4168594166 --- /dev/null +++ b/packages/dht/src/browser/createGeoipLocator.ts @@ -0,0 +1,5 @@ +import type { GeoIpLocator } from '@streamr/geoip-location' + +export const createGeoipLocator = (_geoIpDatabaseFolder: string): Promise => { + throw new Error('GeoIpLocator is not supported in browser environment') +} diff --git a/packages/dht/src/browser/isBrowserEnvironment.ts b/packages/dht/src/browser/isBrowserEnvironment.ts new file mode 100644 index 0000000000..ccc0a7d7af --- /dev/null +++ b/packages/dht/src/browser/isBrowserEnvironment.ts @@ -0,0 +1 @@ +export const isBrowserEnvironment = true diff --git a/packages/dht/src/connection/Connection.ts b/packages/dht/src/connection/Connection.ts index a0bf8a052e..4d3141ed8f 100644 --- a/packages/dht/src/connection/Connection.ts +++ b/packages/dht/src/connection/Connection.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { ConnectionID, ConnectionType, ConnectionEvents } from './IConnection' import { v4 as uuid } from 'uuid' diff --git a/packages/dht/src/connection/ConnectionLockRpcLocal.ts b/packages/dht/src/connection/ConnectionLockRpcLocal.ts index 2a09fc4212..48228fcdca 100644 --- a/packages/dht/src/connection/ConnectionLockRpcLocal.ts +++ b/packages/dht/src/connection/ConnectionLockRpcLocal.ts @@ -12,7 +12,7 @@ import { } from '../../generated/packages/dht/protos/DhtRpc' import { IConnectionLockRpc } from '../../generated/packages/dht/protos/DhtRpc.server' import { DhtCallContext } from '../rpc-protocol/DhtCallContext' -import { getNodeIdOrUnknownFromPeerDescriptor } from './ConnectionManager' +import { getNodeIdOrUnknownFromPeerDescriptor } from './helpers/getNodeIdOrUnknownFromPeerDescriptor' import { LockID } from './ConnectionLockStates' import { DhtAddress, areEqualPeerDescriptors, toNodeId } from '../identifiers' diff --git a/packages/dht/src/connection/ConnectionManager.ts b/packages/dht/src/connection/ConnectionManager.ts index a9023c3afa..763706cb64 100644 --- a/packages/dht/src/connection/ConnectionManager.ts +++ b/packages/dht/src/connection/ConnectionManager.ts @@ -28,6 +28,7 @@ import { ConnectionsView } from './ConnectionsView' import { OutputBuffer } from './OutputBuffer' import { IConnection } from './IConnection' import { PendingConnection } from './PendingConnection' +import { getNodeIdOrUnknownFromPeerDescriptor } from './helpers/getNodeIdOrUnknownFromPeerDescriptor' export interface ConnectionManagerOptions { maxConnections?: number @@ -99,23 +100,6 @@ type Endpoint = ConnectedEndpoint | ConnectingEndpoint const INTERNAL_SERVICE_ID = 'system/connection-manager' -// Form an string representation from a peer description which can be undefined. This output -// should only be used only for log output. TODO remove this method if we no longer use -// peerDescriptors which can be undefined, e.g. -// - if we refactor ConnectionManager so that it doesn't process handshake requests too early -// and therefore this.localPeerDescriptor can't be undefine (NET-1129) -// - if the peerDescriptor of ManagedConnection is always available -// - if we create stricter types for incoming messages (message.sourceDescriptor or -// disconnectNotice.peerDescriptor) -// - if ManagedConnection#peerDescriptor is never undefined -export const getNodeIdOrUnknownFromPeerDescriptor = (peerDescriptor: PeerDescriptor | undefined): string => { - if (peerDescriptor !== undefined) { - return toNodeId(peerDescriptor) - } else { - return 'unknown' - } -} - export class ConnectionManager extends EventEmitter implements ITransport, ConnectionsView, ConnectionLocker { private options: ConnectionManagerOptions diff --git a/packages/dht/src/connection/ConnectorFacade.ts b/packages/dht/src/connection/ConnectorFacade.ts index 58a3ad164f..50c38cabe9 100644 --- a/packages/dht/src/connection/ConnectorFacade.ts +++ b/packages/dht/src/connection/ConnectorFacade.ts @@ -7,7 +7,8 @@ import { ITransport } from '../transport/ITransport' import { PortRange, TlsCertificate } from './ConnectionManager' import { Simulator } from './simulator/Simulator' import { SimulatorConnector } from './simulator/SimulatorConnector' -import { IceServer, WebrtcConnector } from './webrtc/WebrtcConnector' +import { WebrtcConnector } from './webrtc/WebrtcConnector' +import type { IceServer } from './webrtc/types' import { WebsocketClientConnector } from './websocket/WebsocketClientConnector' import { DhtAddress } from '../identifiers' import { WebsocketServerConnector, WebsocketServerConnectorOptions } from './websocket/WebsocketServerConnector' diff --git a/packages/dht/src/connection/ManagedConnection.ts b/packages/dht/src/connection/ManagedConnection.ts index 36c15c1dae..b17d5f9d20 100644 --- a/packages/dht/src/connection/ManagedConnection.ts +++ b/packages/dht/src/connection/ManagedConnection.ts @@ -2,8 +2,8 @@ import { ConnectionID, IConnection } from './IConnection' import * as Err from '../helpers/errors' import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { Logger } from '@streamr/utils' -import EventEmitter from 'eventemitter3' -import { getNodeIdOrUnknownFromPeerDescriptor } from './ConnectionManager' +import { EventEmitter } from 'eventemitter3' +import { getNodeIdOrUnknownFromPeerDescriptor } from './helpers/getNodeIdOrUnknownFromPeerDescriptor' import { DhtAddress, toNodeId } from '../identifiers' import { createRandomConnectionId } from './Connection' diff --git a/packages/dht/src/connection/PendingConnection.ts b/packages/dht/src/connection/PendingConnection.ts index b0c0c05bcd..d6bb7a0503 100644 --- a/packages/dht/src/connection/PendingConnection.ts +++ b/packages/dht/src/connection/PendingConnection.ts @@ -1,7 +1,7 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { Logger, setAbortableTimeout } from '@streamr/utils' -import { getNodeIdOrUnknownFromPeerDescriptor } from './ConnectionManager' +import { getNodeIdOrUnknownFromPeerDescriptor } from './helpers/getNodeIdOrUnknownFromPeerDescriptor' import { IConnection } from './IConnection' export interface PendingConnectionEvents { diff --git a/packages/dht/src/connection/connectivityChecker.ts b/packages/dht/src/connection/connectivityChecker.ts index b924e4d923..23e144d603 100644 --- a/packages/dht/src/connection/connectivityChecker.ts +++ b/packages/dht/src/connection/connectivityChecker.ts @@ -6,7 +6,7 @@ import { Message, PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { IConnection } from './IConnection' -import { WebsocketClientConnection } from './websocket/NodeWebsocketClientConnection' +import { WebsocketClientConnection } from '@/WebsocketClientConnection' import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketClientConnector' import { isMaybeSupportedProtocolVersion } from '../helpers/version' diff --git a/packages/dht/src/connection/connectivityRequestHandler.ts b/packages/dht/src/connection/connectivityRequestHandler.ts index 1fdb5f8957..89baca0233 100644 --- a/packages/dht/src/connection/connectivityRequestHandler.ts +++ b/packages/dht/src/connection/connectivityRequestHandler.ts @@ -11,7 +11,7 @@ import { IConnection } from './IConnection' import { WebsocketServerConnection } from './websocket/WebsocketServerConnection' import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketClientConnector' import { LOCAL_PROTOCOL_VERSION } from '../helpers/version' -import { GeoIpLocator } from '@streamr/geoip-location' +import type { GeoIpLocator } from '@streamr/geoip-location' export const DISABLE_CONNECTIVITY_PROBE = 0 diff --git a/packages/dht/src/connection/helpers/getNodeIdOrUnknownFromPeerDescriptor.ts b/packages/dht/src/connection/helpers/getNodeIdOrUnknownFromPeerDescriptor.ts new file mode 100644 index 0000000000..9b33c318a6 --- /dev/null +++ b/packages/dht/src/connection/helpers/getNodeIdOrUnknownFromPeerDescriptor.ts @@ -0,0 +1,27 @@ +import type { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' +import { toNodeId } from '../../identifiers' + +/** + * Retrieves a string representation of a node ID from a given peer descriptor. + * If the peer descriptor is undefined, it returns 'unknown'. + * + * This function is intended for logging purposes only and should be removed + * if the conditions outlined in the TODO comment are met, such as: + * - Refactoring ConnectionManager to prevent early processing of handshake requests, + * ensuring this.localPeerDescriptor is never undefined (NET-1129). + * - Ensuring the peerDescriptor of ManagedConnection is always available. + * - Creating stricter types for incoming messages, such as message.sourceDescriptor + * or disconnectNotice.peerDescriptor. + * - Guaranteeing that ManagedConnection#peerDescriptor is never undefined. + * + * @param peerDescriptor - The peer descriptor from which to derive the node ID, + * or undefined if not available. + * @returns A string representation of the node ID or 'unknown' if the peer descriptor is undefined. + */ +export const getNodeIdOrUnknownFromPeerDescriptor = (peerDescriptor: PeerDescriptor | undefined): string => { + if (peerDescriptor !== undefined) { + return toNodeId(peerDescriptor) + } else { + return 'unknown' + } +} diff --git a/packages/dht/src/connection/webrtc/WebrtcConnector.ts b/packages/dht/src/connection/webrtc/WebrtcConnector.ts index 694673b7b7..96dbe41cf9 100644 --- a/packages/dht/src/connection/webrtc/WebrtcConnector.ts +++ b/packages/dht/src/connection/webrtc/WebrtcConnector.ts @@ -7,7 +7,7 @@ import { } from '../../../generated/packages/dht/protos/DhtRpc' import { ITransport } from '../../transport/ITransport' import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator' -import { NodeWebrtcConnection } from './NodeWebrtcConnection' +import { WebrtcConnection } from '@/WebrtcConnection' import { WebrtcConnectorRpcRemote } from './WebrtcConnectorRpcRemote' import { WebrtcConnectorRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client' import { Logger } from '@streamr/utils' @@ -20,6 +20,7 @@ import { getOfferer } from '../../helpers/offering' import { acceptHandshake, createIncomingHandshaker, createOutgoingHandshaker, rejectHandshake } from '../Handshaker' import { isMaybeSupportedProtocolVersion } from '../../helpers/version' import { PendingConnection } from '../PendingConnection' +import type { IceServer } from './types' const logger = new Logger('WebrtcConnector') @@ -32,8 +33,6 @@ export const replaceInternalIpWithExternalIp = (candidate: string, ip: string): return parsed.join(' ') } -export const EARLY_TIMEOUT = 5000 - export interface WebrtcConnectorOptions { onNewConnection: (connection: PendingConnection) => boolean transport: ITransport @@ -46,17 +45,9 @@ export interface WebrtcConnectorOptions { portRange?: PortRange } -export interface IceServer { - url: string - port: number - username?: string - password?: string - tcp?: boolean -} - export interface ConnectingConnection { managedConnection: PendingConnection - connection: NodeWebrtcConnection + connection: WebrtcConnection } export class WebrtcConnector { @@ -204,8 +195,8 @@ export class WebrtcConnector { return pendingConnection } - private createConnection(targetPeerDescriptor: PeerDescriptor): NodeWebrtcConnection { - return new NodeWebrtcConnection({ + private createConnection(targetPeerDescriptor: PeerDescriptor): WebrtcConnection { + return new WebrtcConnection({ remotePeerDescriptor: targetPeerDescriptor, iceServers: this.options.iceServers, bufferThresholdLow: this.options.bufferThresholdLow, diff --git a/packages/dht/src/connection/webrtc/WebrtcConnectorRpcLocal.ts b/packages/dht/src/connection/webrtc/WebrtcConnectorRpcLocal.ts index 84e18284a0..8c91b542bf 100644 --- a/packages/dht/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +++ b/packages/dht/src/connection/webrtc/WebrtcConnectorRpcLocal.ts @@ -11,7 +11,7 @@ import { import { IWebrtcConnectorRpc } from '../../../generated/packages/dht/protos/DhtRpc.server' import { DhtCallContext } from '../../rpc-protocol/DhtCallContext' import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator' -import { NodeWebrtcConnection } from './NodeWebrtcConnection' +import type { WebrtcConnection } from '@/WebrtcConnection' import { DhtAddress, toNodeId } from '../../identifiers' import { ConnectionID } from '../IConnection' import { ConnectingConnection } from './WebrtcConnector' @@ -50,7 +50,7 @@ export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc { async rtcOffer(request: RtcOffer, context: ServerCallContext): Promise { const remotePeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor! const nodeId = toNodeId(remotePeerDescriptor) - let connection: NodeWebrtcConnection + let connection: WebrtcConnection let pendingConnection: PendingConnection if (!this.options.ongoingConnectAttempts.has(nodeId)) { diff --git a/packages/dht/src/connection/webrtc/consts.ts b/packages/dht/src/connection/webrtc/consts.ts new file mode 100644 index 0000000000..c07acfd5eb --- /dev/null +++ b/packages/dht/src/connection/webrtc/consts.ts @@ -0,0 +1 @@ +export const EARLY_TIMEOUT = 5000 diff --git a/packages/dht/src/connection/webrtc/iceServerAsString.ts b/packages/dht/src/connection/webrtc/iceServerAsString.ts index c204464c07..4ffdb588e8 100644 --- a/packages/dht/src/connection/webrtc/iceServerAsString.ts +++ b/packages/dht/src/connection/webrtc/iceServerAsString.ts @@ -1,4 +1,4 @@ -import { IceServer } from './WebrtcConnector' +import { IceServer } from './types' export function iceServerAsString({ url, port, username, password, tcp }: IceServer): string { const [protocol, hostname] = url.split(':') diff --git a/packages/dht/src/connection/webrtc/types.ts b/packages/dht/src/connection/webrtc/types.ts new file mode 100644 index 0000000000..f0b1acb566 --- /dev/null +++ b/packages/dht/src/connection/webrtc/types.ts @@ -0,0 +1,7 @@ +export interface IceServer { + url: string + port: number + username?: string + password?: string + tcp?: boolean +} diff --git a/packages/dht/src/connection/websocket/AbstractWebsocketClientConnection.ts b/packages/dht/src/connection/websocket/AbstractWebsocketClientConnection.ts index 1db4e88e47..fdc2565ff7 100644 --- a/packages/dht/src/connection/websocket/AbstractWebsocketClientConnection.ts +++ b/packages/dht/src/connection/websocket/AbstractWebsocketClientConnection.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { createRandomConnectionId } from '../Connection' import { ConnectionEvents, ConnectionID, ConnectionType, IConnection } from '../IConnection' import { Logger } from '@streamr/utils' diff --git a/packages/dht/src/connection/websocket/AutoCertifierClientFacade.ts b/packages/dht/src/connection/websocket/AutoCertifierClientFacade.ts index e228801c17..92851181da 100644 --- a/packages/dht/src/connection/websocket/AutoCertifierClientFacade.ts +++ b/packages/dht/src/connection/websocket/AutoCertifierClientFacade.ts @@ -1,36 +1,14 @@ import { - AutoCertifierClient, - HasSessionRequest, - HasSessionResponse, - CertifiedSubdomain, + type CertifiedSubdomain, SERVICE_ID as AUTO_CERTIFIER_SERVICE_ID, - HasSession } from '@streamr/autocertifier-client' import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator' import { Logger, waitForEvent } from '@streamr/utils' import { ITransport } from '../../transport/ITransport' +import { createDefaultAutocertifierClient } from '@/createDefaultAutocertifierClient' const START_TIMEOUT = 60 * 1000 -const defaultAutoCertifierClientFactory = ( - configFile: string, - autoCertifierUrl: string, - autoCertifierRpcCommunicator: ListeningRpcCommunicator, - wsServerPort: number -) => new AutoCertifierClient( - configFile, - wsServerPort, - autoCertifierUrl, - (_serviceId: string, rpcMethodName: string, method: HasSession) => { - autoCertifierRpcCommunicator.registerRpcMethod( - HasSessionRequest, - HasSessionResponse, - rpcMethodName, - method - ) - } -) - export interface IAutoCertifierClient { start(): Promise stop(): void @@ -62,7 +40,7 @@ export class AutoCertifierClientFacade { this.options = options this.rpcCommunicator = new ListeningRpcCommunicator(AUTO_CERTIFIER_SERVICE_ID, options.transport) this.autoCertifierClient = options.createClientFactory ? options.createClientFactory() - : defaultAutoCertifierClientFactory( + : createDefaultAutocertifierClient( options.configFile, options.url, this.rpcCommunicator, diff --git a/packages/dht/src/connection/websocket/WebsocketClientConnector.ts b/packages/dht/src/connection/websocket/WebsocketClientConnector.ts index 5dc5b0e573..4fb0b51178 100644 --- a/packages/dht/src/connection/websocket/WebsocketClientConnector.ts +++ b/packages/dht/src/connection/websocket/WebsocketClientConnector.ts @@ -1,4 +1,4 @@ -import { WebsocketClientConnection } from './NodeWebsocketClientConnection' +import { WebsocketClientConnection } from '@/WebsocketClientConnection' import { ConnectionType } from '../IConnection' import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator' import { WebsocketClientConnectorRpcLocal } from './WebsocketClientConnectorRpcLocal' @@ -7,13 +7,13 @@ import { PeerDescriptor, WebsocketConnectionRequest } from '../../../generated/packages/dht/protos/DhtRpc' -import { WebsocketServer } from './WebsocketServer' +import type { IWebsocketServer } from './types' import { createOutgoingHandshaker } from '../Handshaker' import { ServerCallContext } from '@protobuf-ts/runtime-rpc' import { expectedConnectionType } from '../../helpers/Connectivity' import { Empty } from '../../../generated/google/protobuf/empty' import { DhtAddress, toNodeId } from '../../identifiers' -import { GeoIpLocator } from '@streamr/geoip-location' +import type { GeoIpLocator } from '@streamr/geoip-location' import { PendingConnection } from '../PendingConnection' export type Action = 'connectivityRequest' | 'connectivityProbe' @@ -31,7 +31,7 @@ export interface WebsocketClientConnectorOptions { export class WebsocketClientConnector { public static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/websocket-connector' - private readonly websocketServer?: WebsocketServer + private readonly websocketServer?: IWebsocketServer private geoIpLocator?: GeoIpLocator private localPeerDescriptor?: PeerDescriptor diff --git a/packages/dht/src/connection/websocket/WebsocketServerConnection.ts b/packages/dht/src/connection/websocket/WebsocketServerConnection.ts index fe0378021f..4d7f599c0b 100644 --- a/packages/dht/src/connection/websocket/WebsocketServerConnection.ts +++ b/packages/dht/src/connection/websocket/WebsocketServerConnection.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { IConnection, ConnectionID, ConnectionEvents, ConnectionType } from '../IConnection' import WebSocket from 'ws' import { Logger } from '@streamr/utils' diff --git a/packages/dht/src/connection/websocket/WebsocketServerConnector.ts b/packages/dht/src/connection/websocket/WebsocketServerConnector.ts index 06f09dfc8b..7492f66c85 100644 --- a/packages/dht/src/connection/websocket/WebsocketServerConnector.ts +++ b/packages/dht/src/connection/websocket/WebsocketServerConnector.ts @@ -1,7 +1,8 @@ -import { GeoIpLocator } from '@streamr/geoip-location' +import type { GeoIpLocator } from '@streamr/geoip-location' +import { createGeoipLocator } from '@/createGeoipLocator' import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator' import { Action, connectivityMethodToWebsocketUrl } from './WebsocketClientConnector' -import { WebsocketServer } from './WebsocketServer' +import { WebsocketServer } from '@/WebsocketServer' import { areEqualPeerDescriptors, DhtAddress, toNodeId } from '../../identifiers' import { AutoCertifierClientFacade } from './AutoCertifierClientFacade' import { ConnectivityResponse, HandshakeError, PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' @@ -96,10 +97,8 @@ export class WebsocketServerConnector { }) if (this.options.geoIpDatabaseFolder) { - const geoIpLocator = new GeoIpLocator(this.options.geoIpDatabaseFolder) try { - await geoIpLocator.start() - this.geoIpLocator = geoIpLocator + this.geoIpLocator = await createGeoipLocator(this.options.geoIpDatabaseFolder) } catch (err) { logger.error('Failed to start GeoIpLocator', { err }) } diff --git a/packages/dht/src/connection/websocket/types.ts b/packages/dht/src/connection/websocket/types.ts new file mode 100644 index 0000000000..974f21c32c --- /dev/null +++ b/packages/dht/src/connection/websocket/types.ts @@ -0,0 +1,20 @@ +import type { EventEmitter } from 'eventemitter3' +import type { PortRange, TlsCertificate } from '../ConnectionManager' +import type { IConnection } from '../IConnection' + +export interface WebsocketServerEvents { + connected: ((connection: IConnection) => void) +} + +export interface WebsocketServerOptions { + portRange: PortRange + enableTls: boolean + tlsCertificate?: TlsCertificate + maxMessageSize?: number +} + +export interface IWebsocketServer extends EventEmitter { + start(): Promise + stop(): Promise + updateCertificate(cert: string, key: string): void +} diff --git a/packages/dht/src/dht/DhtNode.ts b/packages/dht/src/dht/DhtNode.ts index 11f7f16bd1..9c632c4772 100644 --- a/packages/dht/src/dht/DhtNode.ts +++ b/packages/dht/src/dht/DhtNode.ts @@ -13,8 +13,7 @@ import type { MarkRequired } from 'ts-essentials' import { ConnectionLocker, ConnectionManager, PortRange, TlsCertificate } from '../connection/ConnectionManager' import { ConnectionsView } from '../connection/ConnectionsView' import { DefaultConnectorFacade, DefaultConnectorFacadeOptions } from '../connection/ConnectorFacade' -import { IceServer } from '../connection/webrtc/WebrtcConnector' -import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment' +import type { IceServer } from '../connection/webrtc/types' import { createPeerDescriptor } from '../helpers/createPeerDescriptor' import { DhtAddress, KADEMLIA_ID_LENGTH_IN_BYTES, toNodeId } from '../identifiers' import { Any } from '../../generated/google/protobuf/any' @@ -54,6 +53,8 @@ import { LocalDataStore } from './store/LocalDataStore' import { StoreManager } from './store/StoreManager' import { StoreRpcRemote } from './store/StoreRpcRemote' import { getLocalRegionByCoordinates, getLocalRegionWithCache } from '@streamr/cdn-location' +import { isBrowserEnvironment } from '@/isBrowserEnvironment' +import { CONTROL_LAYER_NODE_SERVICE_ID } from './consts' export interface DhtNodeEvents extends TransportEvents { nearbyContactAdded: (peerDescriptor: PeerDescriptor) => void @@ -132,9 +133,6 @@ const logger = new Logger('DhtNode') export const NUMBER_OF_NODES_PER_KBUCKET_DEFAULT = 8 const PERIODICAL_PING_INTERVAL = 60 * 1000 -// TODO move this to trackerless-network package and change serviceId to be a required paramater -export const CONTROL_LAYER_NODE_SERVICE_ID = 'layer0' - export class DhtNode extends EventEmitter implements ITransport { private readonly options: StrictDhtNodeOptions @@ -200,7 +198,7 @@ export class DhtNode extends EventEmitter implements ITransport { logger.trace(`Starting new Streamr Network DHT Node with serviceId ${this.options.serviceId}`) this.started = true - if (isBrowserEnvironment()) { + if (isBrowserEnvironment) { this.options.websocketPortRange = undefined if (this.options.peerDescriptor) { this.options.peerDescriptor.websocket = undefined diff --git a/packages/dht/src/dht/PeerManager.ts b/packages/dht/src/dht/PeerManager.ts index d05cfb92db..1039f58e84 100644 --- a/packages/dht/src/dht/PeerManager.ts +++ b/packages/dht/src/dht/PeerManager.ts @@ -1,11 +1,9 @@ -import { - Logger -} from '@streamr/utils' -import EventEmitter from 'eventemitter3' +import { Logger } from '@streamr/utils' +import { EventEmitter } from 'eventemitter3' import KBucket from 'k-bucket' import { LockID } from '../connection/ConnectionLockStates' import { ConnectionLocker } from '../connection/ConnectionManager' -import { DhtAddress, DhtAddressRaw, toNodeId, toDhtAddressRaw } from '../identifiers' +import { DhtAddress, toNodeId, toDhtAddressRaw } from '../identifiers' import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' @@ -54,10 +52,6 @@ export interface PeerManagerEvents { kBucketEmpty: () => void } -export const getDistance = (nodeIdOrDataKeyRaw1: DhtAddressRaw, nodeIdOrDataKeyRaw2: DhtAddressRaw): number => { - return KBucket.distance(nodeIdOrDataKeyRaw1, nodeIdOrDataKeyRaw2) -} - export class PeerManager extends EventEmitter { // Glossary: diff --git a/packages/dht/src/dht/consts.ts b/packages/dht/src/dht/consts.ts new file mode 100644 index 0000000000..eee28b1fd8 --- /dev/null +++ b/packages/dht/src/dht/consts.ts @@ -0,0 +1,2 @@ +// TODO move this to trackerless-network package and change serviceId to be a required paramater +export const CONTROL_LAYER_NODE_SERVICE_ID = 'layer0' diff --git a/packages/dht/src/dht/contact/ContactList.ts b/packages/dht/src/dht/contact/ContactList.ts index 8e4e6a0ff5..05f6f41c99 100644 --- a/packages/dht/src/dht/contact/ContactList.ts +++ b/packages/dht/src/dht/contact/ContactList.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { DhtAddress } from '../../identifiers' export interface Events { diff --git a/packages/dht/src/dht/contact/RingContactList.ts b/packages/dht/src/dht/contact/RingContactList.ts index fea502e8a8..27bf9ebb65 100644 --- a/packages/dht/src/dht/contact/RingContactList.ts +++ b/packages/dht/src/dht/contact/RingContactList.ts @@ -2,7 +2,7 @@ import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' import { OrderedMap } from '@js-sdsl/ordered-map' import { RingDistance, RingId, RingIdRaw, getLeftDistance, getRightDistance, getRingIdFromPeerDescriptor, getRingIdFromRaw } from './ringIdentifiers' import { DhtAddress, toNodeId } from '../../identifiers' -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { Events } from './ContactList' export interface RingContacts { diff --git a/packages/dht/src/dht/contact/SortedContactList.ts b/packages/dht/src/dht/contact/SortedContactList.ts index 73c0055022..f110ae014e 100755 --- a/packages/dht/src/dht/contact/SortedContactList.ts +++ b/packages/dht/src/dht/contact/SortedContactList.ts @@ -1,7 +1,7 @@ import { Events } from './ContactList' import sortedIndexBy from 'lodash/sortedIndexBy' -import EventEmitter from 'eventemitter3' -import { getDistance } from '../PeerManager' +import { EventEmitter } from 'eventemitter3' +import { getPeerDistance } from '../helpers/getPeerDistance' import { DhtAddress, toDhtAddressRaw } from '../../identifiers' // add other getters in the future if needed @@ -120,7 +120,7 @@ export class SortedContactList DhtAddress }> extend // TODO inline this method? private distanceToReferenceId(id: DhtAddress): number { // TODO maybe this class should store the referenceId also as DhtAddressRaw so that we don't need to convert it here? - return getDistance(toDhtAddressRaw(this.options.referenceId), toDhtAddressRaw(id)) + return getPeerDistance(toDhtAddressRaw(this.options.referenceId), toDhtAddressRaw(id)) } public removeContact(id: DhtAddress): boolean { diff --git a/packages/dht/src/dht/contact/getClosestNodes.ts b/packages/dht/src/dht/contact/getClosestNodes.ts index 864687b807..2266d1ee52 100644 --- a/packages/dht/src/dht/contact/getClosestNodes.ts +++ b/packages/dht/src/dht/contact/getClosestNodes.ts @@ -1,4 +1,4 @@ -import { PeerDescriptor } from '../../exports' +import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' import { DhtAddress } from '../../identifiers' import { Contact } from './Contact' import { SortedContactList } from './SortedContactList' diff --git a/packages/dht/src/dht/discovery/DiscoverySession.ts b/packages/dht/src/dht/discovery/DiscoverySession.ts index 700aaca223..940e039390 100644 --- a/packages/dht/src/dht/discovery/DiscoverySession.ts +++ b/packages/dht/src/dht/discovery/DiscoverySession.ts @@ -3,7 +3,8 @@ import { v4 } from 'uuid' import { DhtAddress, toNodeId, toDhtAddressRaw } from '../../identifiers' import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' import { DhtNodeRpcRemote } from '../DhtNodeRpcRemote' -import { PeerManager, getDistance } from '../PeerManager' +import { PeerManager } from '../PeerManager' +import { getPeerDistance } from '../helpers/getPeerDistance' import { getClosestNodes } from '../contact/getClosestNodes' const logger = new Logger('DiscoverySession') @@ -60,10 +61,10 @@ export class DiscoverySession { this.ongoingRequests.delete(nodeId) const targetId = toDhtAddressRaw(this.options.targetId) const oldClosestNeighbor = this.getClosestNeighbor() - const oldClosestDistance = getDistance(targetId, oldClosestNeighbor.nodeId) + const oldClosestDistance = getPeerDistance(targetId, oldClosestNeighbor.nodeId) this.addContacts(contacts) const newClosestNeighbor = this.getClosestNeighbor() - const newClosestDistance = getDistance(targetId, newClosestNeighbor.nodeId) + const newClosestDistance = getPeerDistance(targetId, newClosestNeighbor.nodeId) if (newClosestDistance >= oldClosestDistance) { this.noProgressCounter++ } diff --git a/packages/dht/src/dht/discovery/PeerDiscovery.ts b/packages/dht/src/dht/discovery/PeerDiscovery.ts index b1dd5d1663..42ea56e029 100644 --- a/packages/dht/src/dht/discovery/PeerDiscovery.ts +++ b/packages/dht/src/dht/discovery/PeerDiscovery.ts @@ -16,7 +16,7 @@ import { getClosestNodes } from '../contact/getClosestNodes' import { RingIdRaw, getRingIdRawFromPeerDescriptor } from '../contact/ringIdentifiers' import { DiscoverySession } from './DiscoverySession' import { RingDiscoverySession } from './RingDiscoverySession' -import { CONTROL_LAYER_NODE_SERVICE_ID } from '../DhtNode' +import { CONTROL_LAYER_NODE_SERVICE_ID } from '../consts' interface PeerDiscoveryOptions { localPeerDescriptor: PeerDescriptor diff --git a/packages/dht/src/dht/helpers/getPeerDistance.ts b/packages/dht/src/dht/helpers/getPeerDistance.ts new file mode 100644 index 0000000000..592619929d --- /dev/null +++ b/packages/dht/src/dht/helpers/getPeerDistance.ts @@ -0,0 +1,9 @@ +import KBucket from 'k-bucket' +import { DhtAddressRaw } from '../../identifiers' + +export const getPeerDistance = ( + nodeIdOrDataKeyRaw1: DhtAddressRaw, + nodeIdOrDataKeyRaw2: DhtAddressRaw +): number => { + return KBucket.distance(nodeIdOrDataKeyRaw1, nodeIdOrDataKeyRaw2) +} diff --git a/packages/dht/src/dht/recursive-operation/RecursiveOperationManager.ts b/packages/dht/src/dht/recursive-operation/RecursiveOperationManager.ts index bea14f6bc2..0cffa8b837 100644 --- a/packages/dht/src/dht/recursive-operation/RecursiveOperationManager.ts +++ b/packages/dht/src/dht/recursive-operation/RecursiveOperationManager.ts @@ -24,8 +24,8 @@ import { createRouteMessageAck } from '../routing/RouterRpcLocal' import { ServiceID } from '../../types/ServiceID' import { RecursiveOperationRpcLocal } from './RecursiveOperationRpcLocal' import { DhtAddress, areEqualPeerDescriptors, toDhtAddress, toNodeId, toDhtAddressRaw } from '../../identifiers' -import { getDistance } from '../PeerManager' -import { ConnectionsView } from '../../exports' +import { getPeerDistance } from '../helpers/getPeerDistance' +import { ConnectionsView } from '../../connection/ConnectionsView' interface RecursiveOperationManagerOptions { rpcCommunicator: RoutingRpcCommunicator @@ -233,8 +233,8 @@ export class RecursiveOperationManager { private isPeerCloserToIdThanSelf(peer: PeerDescriptor, nodeIdOrDataKey: DhtAddress): boolean { const nodeIdOrDataKeyRaw = toDhtAddressRaw(nodeIdOrDataKey) - const distance1 = getDistance(peer.nodeId, nodeIdOrDataKeyRaw) - const distance2 = getDistance(this.options.localPeerDescriptor.nodeId, nodeIdOrDataKeyRaw) + const distance1 = getPeerDistance(peer.nodeId, nodeIdOrDataKeyRaw) + const distance2 = getPeerDistance(this.options.localPeerDescriptor.nodeId, nodeIdOrDataKeyRaw) return distance1 < distance2 } diff --git a/packages/dht/src/dht/recursive-operation/RecursiveOperationSession.ts b/packages/dht/src/dht/recursive-operation/RecursiveOperationSession.ts index 18dfde8355..b23d98c055 100644 --- a/packages/dht/src/dht/recursive-operation/RecursiveOperationSession.ts +++ b/packages/dht/src/dht/recursive-operation/RecursiveOperationSession.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { v4 } from 'uuid' import { DataEntry, diff --git a/packages/dht/src/dht/routing/RoutingSession.ts b/packages/dht/src/dht/routing/RoutingSession.ts index 355078b3c2..4237d76849 100644 --- a/packages/dht/src/dht/routing/RoutingSession.ts +++ b/packages/dht/src/dht/routing/RoutingSession.ts @@ -1,6 +1,6 @@ import { SortedContactList } from '../contact/SortedContactList' import { Logger } from '@streamr/utils' -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { v4 } from 'uuid' import { PeerDescriptor, RouteMessageWrapper } from '../../../generated/packages/dht/protos/DhtRpc' import { RouterRpcRemote, ROUTING_TIMEOUT } from './RouterRpcRemote' diff --git a/packages/dht/src/exports.ts b/packages/dht/src/exports.ts index 6fe245fe1e..bfc02b6260 100644 --- a/packages/dht/src/exports.ts +++ b/packages/dht/src/exports.ts @@ -12,9 +12,9 @@ export type { LockID } from './connection/ConnectionLockStates' export { DefaultConnectorFacade } from './connection/ConnectorFacade' export type { DhtRpcOptions } from './rpc-protocol/DhtRpcOptions' export { RpcRemote, EXISTING_CONNECTION_TIMEOUT } from './dht/contact/RpcRemote' -export type { IceServer } from './connection/webrtc/WebrtcConnector' +export type { IceServer } from './connection/webrtc/types' export { DhtCallContext } from './rpc-protocol/DhtCallContext' -export { WebsocketClientConnection } from './connection/websocket/NodeWebsocketClientConnection' +export { WebsocketClientConnection } from '@/WebsocketClientConnection' export { ManagedConnection } from './connection/ManagedConnection' export { PendingConnection } from './connection/PendingConnection' export type { IConnection } from './connection/IConnection' diff --git a/packages/dht/src/helpers/browser/isBrowserEnvironment.ts b/packages/dht/src/helpers/browser/isBrowserEnvironment.ts deleted file mode 100644 index ac3c121acb..0000000000 --- a/packages/dht/src/helpers/browser/isBrowserEnvironment.ts +++ /dev/null @@ -1 +0,0 @@ -export const isBrowserEnvironment = (): boolean => false diff --git a/packages/dht/src/helpers/browser/isBrowserEnvironment_override.ts b/packages/dht/src/helpers/browser/isBrowserEnvironment_override.ts deleted file mode 100644 index 38c7c9c2ac..0000000000 --- a/packages/dht/src/helpers/browser/isBrowserEnvironment_override.ts +++ /dev/null @@ -1,3 +0,0 @@ -// webpack overwrites the isBrowserEnvironment.ts with this file when it creates the browser bundle - -export const isBrowserEnvironment = (): boolean => true diff --git a/packages/dht/src/helpers/createPeerDescriptor.ts b/packages/dht/src/helpers/createPeerDescriptor.ts index f9c05f8a14..b7731d7e76 100644 --- a/packages/dht/src/helpers/createPeerDescriptor.ts +++ b/packages/dht/src/helpers/createPeerDescriptor.ts @@ -1,6 +1,5 @@ -import { EcdsaSecp256k1Evm } from '@streamr/utils' -import crypto from 'crypto' -import { isBrowserEnvironment } from '../helpers/browser/isBrowserEnvironment' +import { EcdsaSecp256k1Evm, randomBytes } from '@streamr/utils' +import { isBrowserEnvironment } from '@/isBrowserEnvironment' import { createPeerDescriptorSignaturePayload } from '../helpers/createPeerDescriptorSignaturePayload' import { DhtAddress, DhtAddressRaw, toDhtAddressRaw } from '../identifiers' import { @@ -30,8 +29,8 @@ const calculateNodeIdRaw = async (ipAddress: number, privateKey: Uint8Array): Pr export const createPeerDescriptor = async (connectivityResponse: ConnectivityResponse, region: number, nodeId?: DhtAddress): Promise => { - const privateKey = crypto.randomBytes(32) - const publicKey = crypto.randomBytes(20) // TODO calculate publicKey from privateKey + const privateKey = randomBytes(32) + const publicKey = randomBytes(20) // TODO calculate publicKey from privateKey let nodeIdRaw: DhtAddressRaw if (nodeId !== undefined) { nodeIdRaw = toDhtAddressRaw(nodeId) @@ -40,7 +39,7 @@ export const createPeerDescriptor = async (connectivityResponse: ConnectivityRes } const ret: PeerDescriptor = { nodeId: nodeIdRaw, - type: isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS, + type: isBrowserEnvironment ? NodeType.BROWSER : NodeType.NODEJS, ipAddress: connectivityResponse.ipAddress, region, publicKey diff --git a/packages/dht/src/helpers/offering.ts b/packages/dht/src/helpers/offering.ts index fc103de7c0..297364f8b0 100644 --- a/packages/dht/src/helpers/offering.ts +++ b/packages/dht/src/helpers/offering.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto' +import { computeMd5 } from '@streamr/utils' import { DhtAddress } from '../identifiers' type Offerer = 'local' | 'remote' @@ -10,6 +10,5 @@ export const getOfferer = (localNodeId: DhtAddress, remoteNodeId: DhtAddress): O } const getOfferingHash = (idPair: string): number => { - const buffer = crypto.createHash('md5').update(idPair).digest() - return buffer.readInt32LE(0) + return computeMd5(idPair).readInt32LE(0) } diff --git a/packages/dht/src/helpers/protoClasses.ts b/packages/dht/src/helpers/protoClasses.ts index 1af21d297e..7c42f7903f 100644 --- a/packages/dht/src/helpers/protoClasses.ts +++ b/packages/dht/src/helpers/protoClasses.ts @@ -25,7 +25,6 @@ import { LockRequest, UnlockRequest, LockResponse - } from '../../generated/packages/dht/protos/DhtRpc' export const protoClasses: IMessageType[] = [ diff --git a/packages/dht/src/helpers/protoToString.ts b/packages/dht/src/helpers/protoToString.ts index 0eb1d64e5b..9dc6e2cb40 100644 --- a/packages/dht/src/helpers/protoToString.ts +++ b/packages/dht/src/helpers/protoToString.ts @@ -1,5 +1,4 @@ import { IMessageType } from '@protobuf-ts/runtime' - import { protoClasses } from './protoClasses' import { protoClasses as rpcProtoClasses } from '@streamr/proto-rpc' diff --git a/packages/dht/src/identifiers.ts b/packages/dht/src/identifiers.ts index 1be870bb7d..5177ab7470 100644 --- a/packages/dht/src/identifiers.ts +++ b/packages/dht/src/identifiers.ts @@ -1,5 +1,4 @@ -import { BrandedString, areEqualBinaries, binaryToHex, hexToBinary } from '@streamr/utils' -import crypto from 'crypto' +import { BrandedString, areEqualBinaries, binaryToHex, hexToBinary, randomBytes } from '@streamr/utils' import { PeerDescriptor } from '../generated/packages/dht/protos/DhtRpc' // https://www.scs.stanford.edu/~dm/home/papers/kpos.pdf @@ -25,5 +24,5 @@ export const areEqualPeerDescriptors = (peerDescriptor1: PeerDescriptor, peerDes } export const randomDhtAddress = (): DhtAddress => { - return toDhtAddress(crypto.randomBytes(KADEMLIA_ID_LENGTH_IN_BYTES)) + return toDhtAddress(randomBytes(KADEMLIA_ID_LENGTH_IN_BYTES)) } diff --git a/packages/dht/src/connection/webrtc/NodeWebrtcConnection.ts b/packages/dht/src/nodejs/WebrtcConnection.ts similarity index 88% rename from packages/dht/src/connection/webrtc/NodeWebrtcConnection.ts rename to packages/dht/src/nodejs/WebrtcConnection.ts index 7d0434f50b..88dd2b0916 100644 --- a/packages/dht/src/connection/webrtc/NodeWebrtcConnection.ts +++ b/packages/dht/src/nodejs/WebrtcConnection.ts @@ -1,26 +1,19 @@ -import { IWebrtcConnection, WebrtcConnectionEvents } from './IWebrtcConnection' -import { ConnectionType, IConnection, ConnectionID } from '../IConnection' -import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc' -import EventEmitter from 'eventemitter3' +import { IWebrtcConnection, WebrtcConnectionEvents } from '../connection/webrtc/IWebrtcConnection' +import { ConnectionType, IConnection, ConnectionID } from '../connection/IConnection' +import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' +import { EventEmitter } from 'eventemitter3' import { DataChannel, DescriptionType, PeerConnection, initLogger } from 'node-datachannel' import { Logger } from '@streamr/utils' -import { IllegalRtcPeerConnectionState } from '../../helpers/errors' -import { iceServerAsString } from './iceServerAsString' -import { IceServer, EARLY_TIMEOUT } from './WebrtcConnector' -import { PortRange } from '../ConnectionManager' -import { toNodeId } from '../../identifiers' -import { createRandomConnectionId } from '../Connection' - -const logger = new Logger('NodeWebrtcConnection') - -export interface Params { - remotePeerDescriptor: PeerDescriptor - bufferThresholdHigh?: number - bufferThresholdLow?: number - maxMessageSize?: number - iceServers?: IceServer[] // TODO make this parameter required (empty array is a good fallback which can be set by the caller if needed) - portRange?: PortRange -} +import { IllegalRtcPeerConnectionState } from '../helpers/errors' +import { iceServerAsString } from '../connection/webrtc/iceServerAsString' +import { IceServer } from '../connection/webrtc/types' +import { EARLY_TIMEOUT } from '../connection/webrtc/consts' +import { PortRange } from '../connection/ConnectionManager' +import { toNodeId } from '../identifiers' +import { createRandomConnectionId } from '../connection/Connection' +import type { WebrtcConnectionParams } from '../types/WebrtcConnectionParams' + +const logger = new Logger('WebrtcConnection (Node)') // Re-defined accoring to https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts // because importing single dom definitions in not possible @@ -38,7 +31,7 @@ initLogger('Fatal') type RtcPeerConnectionState = keyof typeof RtcPeerConnectionStateEnum -export class NodeWebrtcConnection extends EventEmitter implements IConnection, IWebrtcConnection { +export class WebrtcConnection extends EventEmitter implements IConnection, IWebrtcConnection { public connectionId: ConnectionID private connection?: PeerConnection @@ -57,7 +50,7 @@ export class NodeWebrtcConnection extends EventEmitter i private offering?: boolean private readonly earlyTimeout: NodeJS.Timeout - constructor(params: Params) { + constructor(params: WebrtcConnectionParams) { super() this.connectionId = createRandomConnectionId() this.iceServers = params.iceServers ?? [] diff --git a/packages/dht/src/connection/websocket/NodeWebsocketClientConnection.ts b/packages/dht/src/nodejs/WebsocketClientConnection.ts similarity index 89% rename from packages/dht/src/connection/websocket/NodeWebsocketClientConnection.ts rename to packages/dht/src/nodejs/WebsocketClientConnection.ts index d0c15c33fd..98fd2263a5 100644 --- a/packages/dht/src/connection/websocket/NodeWebsocketClientConnection.ts +++ b/packages/dht/src/nodejs/WebsocketClientConnection.ts @@ -1,8 +1,8 @@ import { Logger, binaryToUtf8 } from '@streamr/utils' import { WebSocket } from 'ws' -import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection' +import { AbstractWebsocketClientConnection } from '../connection/websocket/AbstractWebsocketClientConnection' -const logger = new Logger('NodeWebsocketClientConnection') +const logger = new Logger('WebsocketClientConnection (Node)') const BINARY_TYPE = 'nodebuffer' diff --git a/packages/dht/src/connection/websocket/WebsocketServer.ts b/packages/dht/src/nodejs/WebsocketServer.ts similarity index 90% rename from packages/dht/src/connection/websocket/WebsocketServer.ts rename to packages/dht/src/nodejs/WebsocketServer.ts index 785de0e403..21cae994aa 100644 --- a/packages/dht/src/connection/websocket/WebsocketServer.ts +++ b/packages/dht/src/nodejs/WebsocketServer.ts @@ -1,32 +1,20 @@ import { createServer as createHttpServer, Server as HttpServer, IncomingMessage, ServerResponse } from 'http' import { createServer as createHttpsServer, Server as HttpsServer } from 'https' -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import WebSocket, { WebSocketServer } from 'ws' -import { WebsocketServerConnection } from './WebsocketServerConnection' +import { WebsocketServerConnection } from '../connection/websocket/WebsocketServerConnection' import { Logger, asAbortable } from '@streamr/utils' import { createSelfSignedCertificate } from '@streamr/autocertifier-client' -import { WebsocketServerStartError } from '../../helpers/errors' -import { PortRange, TlsCertificate } from '../ConnectionManager' +import { WebsocketServerStartError } from '../helpers/errors' import range from 'lodash/range' import fs from 'fs' import { v4 as uuid } from 'uuid' import { parse } from 'url' -import { IConnection } from '../IConnection' +import type { IWebsocketServer, WebsocketServerEvents, WebsocketServerOptions } from '../connection/websocket/types' -const logger = new Logger('WebsocketServer') +const logger = new Logger('WebsocketServer (Node)') -interface WebsocketServerOptions { - portRange: PortRange - enableTls: boolean - tlsCertificate?: TlsCertificate - maxMessageSize?: number -} - -interface Events { - connected: ((connection: IConnection) => void) -} - -export class WebsocketServer extends EventEmitter { +export class WebsocketServer extends EventEmitter implements IWebsocketServer { private httpServer?: HttpServer | HttpsServer private wsServer?: WebSocketServer diff --git a/packages/dht/src/nodejs/createDefaultAutocertifierClient.ts b/packages/dht/src/nodejs/createDefaultAutocertifierClient.ts new file mode 100644 index 0000000000..70c600f3cd --- /dev/null +++ b/packages/dht/src/nodejs/createDefaultAutocertifierClient.ts @@ -0,0 +1,28 @@ +import { + AutoCertifierClient, + HasSessionRequest, + HasSessionResponse, + type HasSession, +} from '@streamr/autocertifier-client' +import { ListeningRpcCommunicator } from '../transport/ListeningRpcCommunicator' + +export const createDefaultAutocertifierClient = ( + configFile: string, + autoCertifierUrl: string, + autoCertifierRpcCommunicator: ListeningRpcCommunicator, + wsServerPort: number +): AutoCertifierClient => { + return new AutoCertifierClient( + configFile, + wsServerPort, + autoCertifierUrl, + (_serviceId: string, rpcMethodName: string, method: HasSession) => { + autoCertifierRpcCommunicator.registerRpcMethod( + HasSessionRequest, + HasSessionResponse, + rpcMethodName, + method + ) + } + ) +} diff --git a/packages/dht/src/nodejs/createGeoipLocator.ts b/packages/dht/src/nodejs/createGeoipLocator.ts new file mode 100644 index 0000000000..36f1eb8f13 --- /dev/null +++ b/packages/dht/src/nodejs/createGeoipLocator.ts @@ -0,0 +1,11 @@ +import { GeoIpLocator } from '@streamr/geoip-location' + +export const createGeoipLocator = async ( + geoIpDatabaseFolder: string +): Promise => { + const geoIpLocator = new GeoIpLocator(geoIpDatabaseFolder) + + await geoIpLocator.start() + + return geoIpLocator +} diff --git a/packages/dht/src/nodejs/isBrowserEnvironment.ts b/packages/dht/src/nodejs/isBrowserEnvironment.ts new file mode 100644 index 0000000000..5f58603e88 --- /dev/null +++ b/packages/dht/src/nodejs/isBrowserEnvironment.ts @@ -0,0 +1 @@ +export const isBrowserEnvironment = false diff --git a/packages/dht/src/types/textencoding.d.ts b/packages/dht/src/nodejs/textencoding.d.ts similarity index 100% rename from packages/dht/src/types/textencoding.d.ts rename to packages/dht/src/nodejs/textencoding.d.ts diff --git a/packages/dht/src/types/WebrtcConnectionParams.ts b/packages/dht/src/types/WebrtcConnectionParams.ts new file mode 100644 index 0000000000..24eff16f79 --- /dev/null +++ b/packages/dht/src/types/WebrtcConnectionParams.ts @@ -0,0 +1,12 @@ +import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' +import { PortRange } from '../connection/ConnectionManager' +import { IceServer } from '../connection/webrtc/types' + +export interface WebrtcConnectionParams { + remotePeerDescriptor: PeerDescriptor + bufferThresholdHigh?: number + bufferThresholdLow?: number + maxMessageSize?: number + iceServers?: IceServer[] // TODO make this parameter required (empty array is a good fallback which can be set by the caller if needed) + portRange?: PortRange +} diff --git a/packages/dht/test/benchmark/WebsocketServerMemoryLeak.test.ts b/packages/dht/test/benchmark/WebsocketServerMemoryLeak.test.ts index ef12daf395..ff1826f4b3 100644 --- a/packages/dht/test/benchmark/WebsocketServerMemoryLeak.test.ts +++ b/packages/dht/test/benchmark/WebsocketServerMemoryLeak.test.ts @@ -1,8 +1,8 @@ /* eslint-disable no-console */ import { wait } from '@streamr/utils' -import { WebsocketServer } from '../../src/connection/websocket/WebsocketServer' -import { WebsocketClientConnection } from '../../src/connection/websocket/NodeWebsocketClientConnection' +import { WebsocketServer } from '@/WebsocketServer' +import { WebsocketClientConnection } from '@/WebsocketClientConnection' // This 'test' is meant to be run manually using the following command: // node --inspect ../../../../node_modules/.bin/jest WebsocketServerMemoryLeak.test.ts diff --git a/packages/dht/test/end-to-end/Layer0Webrtc.test.ts b/packages/dht/test/end-to-end/Layer0Webrtc.test.ts index 73996badea..fa6bd42c7d 100644 --- a/packages/dht/test/end-to-end/Layer0Webrtc.test.ts +++ b/packages/dht/test/end-to-end/Layer0Webrtc.test.ts @@ -3,7 +3,7 @@ import { ConnectionManager } from '../../src/connection/ConnectionManager' import { DhtNode } from '../../src/dht/DhtNode' import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { createMockPeerDescriptor } from '../utils/utils' -import { toNodeId } from '../../src/exports' +import { toNodeId } from './../../src/identifiers' describe('Layer0 with WebRTC connections', () => { diff --git a/packages/dht/test/integration/DhtNode.test.ts b/packages/dht/test/integration/DhtNode.test.ts index bfac847c1c..1822d5139d 100644 --- a/packages/dht/test/integration/DhtNode.test.ts +++ b/packages/dht/test/integration/DhtNode.test.ts @@ -2,7 +2,9 @@ import { until } from '@streamr/utils' import range from 'lodash/range' import without from 'lodash/without' import { DhtNodeRpcLocal } from '../../src/dht/DhtNodeRpcLocal' -import { DhtNode, ListeningRpcCommunicator, toNodeId } from '../../src/exports' +import { toNodeId } from '../../src/identifiers' +import { DhtNode } from '../../src/dht/DhtNode' +import { ListeningRpcCommunicator } from '../../src/transport/ListeningRpcCommunicator' import { ClosestPeersRequest, ClosestPeersResponse, PeerDescriptor, PingRequest, PingResponse } from '../../generated/packages/dht/protos/DhtRpc' import { FakeEnvironment } from '../utils/FakeTransport' import { createMockPeerDescriptor } from '../utils/utils' diff --git a/packages/dht/test/integration/Websocket.test.ts b/packages/dht/test/integration/Websocket.test.ts index de2a6e52c8..65901b93ff 100644 --- a/packages/dht/test/integration/Websocket.test.ts +++ b/packages/dht/test/integration/Websocket.test.ts @@ -1,6 +1,6 @@ -import { WebsocketServer } from '../../src/connection/websocket/WebsocketServer' +import { WebsocketServer } from '@/WebsocketServer' import { IConnection } from '../../src/connection/IConnection' -import { WebsocketClientConnection } from '../../src/connection/websocket/NodeWebsocketClientConnection' +import { WebsocketClientConnection } from '@/WebsocketClientConnection' import { Logger } from '@streamr/utils' const logger = new Logger('Websocket.test') diff --git a/packages/dht/test/unit/AutoCertifierClientFacade.test.ts b/packages/dht/test/unit/AutoCertifierClientFacade.test.ts index 280033d269..99b6da3587 100644 --- a/packages/dht/test/unit/AutoCertifierClientFacade.test.ts +++ b/packages/dht/test/unit/AutoCertifierClientFacade.test.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { AutoCertifierClientFacade, IAutoCertifierClient } from '../../src/connection/websocket/AutoCertifierClientFacade' import { MockTransport } from '../utils/mock/MockTransport' diff --git a/packages/dht/test/unit/ConnectionManager.test.ts b/packages/dht/test/unit/ConnectionManager.test.ts index df96e10f0c..ab768aa779 100644 --- a/packages/dht/test/unit/ConnectionManager.test.ts +++ b/packages/dht/test/unit/ConnectionManager.test.ts @@ -1,6 +1,7 @@ import { MetricsContext } from '@streamr/utils' import { ConnectionManager } from '../../src/connection/ConnectionManager' -import { toNodeId, PendingConnection } from '../../src/exports' +import { toNodeId } from '../../src/identifiers' +import { PendingConnection } from '../../src/connection/PendingConnection' import { FakeConnectorFacade } from '../utils/FakeConnectorFacade' import { MockConnection } from '../utils/mock/MockConnection' import { createMockPeerDescriptor } from '../utils/utils' diff --git a/packages/dht/test/unit/DiscoverySession.test.ts b/packages/dht/test/unit/DiscoverySession.test.ts index 2111eb3163..8e50d3feff 100644 --- a/packages/dht/test/unit/DiscoverySession.test.ts +++ b/packages/dht/test/unit/DiscoverySession.test.ts @@ -1,7 +1,8 @@ import { Multimap, wait } from '@streamr/utils' import sampleSize from 'lodash/sampleSize' import { DhtNodeRpcRemote } from '../../src/dht/DhtNodeRpcRemote' -import { PeerManager, getDistance } from '../../src/dht/PeerManager' +import { PeerManager } from '../../src/dht/PeerManager' +import { getPeerDistance } from '../../src/dht/helpers/getPeerDistance' import { DiscoverySession } from '../../src/dht/discovery/DiscoverySession' import { DhtAddress, toNodeId, toDhtAddressRaw } from '../../src/identifiers' import { NodeType, PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' @@ -79,7 +80,7 @@ describe('DiscoverySession', () => { // Each queried node should closer to the target than the previous queried node, because we // use parallelism=1 and noProgressLimit=1 const distancesToTarget = queriedNodes - .map((nodeId) => getDistance(toDhtAddressRaw(nodeId), toDhtAddressRaw(targetId))) + .map((nodeId) => getPeerDistance(toDhtAddressRaw(nodeId), toDhtAddressRaw(targetId))) for (let i = 1; i < distancesToTarget.length ; i++) { expect(distancesToTarget[i]).toBeLessThan(distancesToTarget[i - 1]) } diff --git a/packages/dht/test/unit/Handshaker.test.ts b/packages/dht/test/unit/Handshaker.test.ts index d06dbcd32d..e51ec44226 100644 --- a/packages/dht/test/unit/Handshaker.test.ts +++ b/packages/dht/test/unit/Handshaker.test.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { acceptHandshake, createHandshakeRequest, diff --git a/packages/dht/test/unit/ManagedConnection.test.ts b/packages/dht/test/unit/ManagedConnection.test.ts index 76ba758255..e62cf9e947 100644 --- a/packages/dht/test/unit/ManagedConnection.test.ts +++ b/packages/dht/test/unit/ManagedConnection.test.ts @@ -1,5 +1,5 @@ import { wait } from '@streamr/utils' -import { ManagedConnection } from '../../src/exports' +import { ManagedConnection } from '../../src/connection/ManagedConnection' import { MockConnection } from '../utils/mock/MockConnection' import { createMockPeerDescriptor } from '../utils/utils' diff --git a/packages/dht/test/unit/PendingConnection.test.ts b/packages/dht/test/unit/PendingConnection.test.ts index df8ea9bfaa..f98628bcfa 100644 --- a/packages/dht/test/unit/PendingConnection.test.ts +++ b/packages/dht/test/unit/PendingConnection.test.ts @@ -1,5 +1,5 @@ import { wait, waitForEvent } from '@streamr/utils' -import { PendingConnection } from '../../src/exports' +import { PendingConnection } from '../../src/connection/PendingConnection' import { createMockPeerDescriptor } from '../utils/utils' import { MockConnection } from '../utils/mock/MockConnection' diff --git a/packages/dht/test/unit/WebrtcConnection.test.ts b/packages/dht/test/unit/WebrtcConnection.test.ts index 1b0ec560ea..2ad4a703e4 100644 --- a/packages/dht/test/unit/WebrtcConnection.test.ts +++ b/packages/dht/test/unit/WebrtcConnection.test.ts @@ -1,14 +1,14 @@ import { waitForEvent } from '@streamr/utils' -import { NodeWebrtcConnection } from '../../src/connection/webrtc/NodeWebrtcConnection' +import { WebrtcConnection } from '@/WebrtcConnection' import { createMockPeerDescriptor } from '../utils/utils' describe('WebrtcConnection', () => { - let connection: NodeWebrtcConnection + let connection: WebrtcConnection beforeEach(() => { const peerDescriptor = createMockPeerDescriptor() - connection = new NodeWebrtcConnection({ + connection = new WebrtcConnection({ remotePeerDescriptor: peerDescriptor }) }) diff --git a/packages/dht/test/unit/WebsocketServer.test.ts b/packages/dht/test/unit/WebsocketServer.test.ts index b389291f51..6b537d936f 100644 --- a/packages/dht/test/unit/WebsocketServer.test.ts +++ b/packages/dht/test/unit/WebsocketServer.test.ts @@ -1,4 +1,4 @@ -import { WebsocketServer } from '../../src/connection/websocket/WebsocketServer' +import { WebsocketServer } from '@/WebsocketServer' describe('WebsocketServer', () => { diff --git a/packages/dht/test/unit/createPeerDescriptor.test.ts b/packages/dht/test/unit/createPeerDescriptor.test.ts index 3b5fdf36bb..cd467d88ad 100644 --- a/packages/dht/test/unit/createPeerDescriptor.test.ts +++ b/packages/dht/test/unit/createPeerDescriptor.test.ts @@ -1,6 +1,6 @@ import { ipv4ToNumber } from '@streamr/utils' import { createPeerDescriptor } from '../../src/helpers/createPeerDescriptor' -import { isBrowserEnvironment } from '../../src/helpers/browser/isBrowserEnvironment' +import { isBrowserEnvironment } from '@/isBrowserEnvironment' import { NodeType } from '../../generated/packages/dht/protos/DhtRpc' import { randomDhtAddress, toDhtAddressRaw } from '../../src/identifiers' import { getRandomRegion } from '../../src/connection/simulator/pings' @@ -18,7 +18,7 @@ describe('createPeerDescriptor', () => { const peerDescriptor = await createPeerDescriptor(connectivityResponse, region) expect(peerDescriptor).toEqual({ nodeId: expect.any(Uint8Array), - type: isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS, + type: isBrowserEnvironment ? NodeType.BROWSER : NodeType.NODEJS, ipAddress: ipv4ToNumber(IP_ADDRESS), publicKey: expect.any(Uint8Array), signature: expect.any(Uint8Array), @@ -38,7 +38,7 @@ describe('createPeerDescriptor', () => { const peerDescriptor = await createPeerDescriptor(connectivityResponse, region) expect(peerDescriptor).toEqual({ nodeId: expect.any(Uint8Array), - type: isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS, + type: isBrowserEnvironment ? NodeType.BROWSER : NodeType.NODEJS, ipAddress: ipv4ToNumber(IP_ADDRESS), publicKey: expect.any(Uint8Array), signature: expect.any(Uint8Array), @@ -59,7 +59,7 @@ describe('createPeerDescriptor', () => { const peerDescriptor = await createPeerDescriptor(connectivityResponse, region, nodeId) expect(peerDescriptor).toEqual({ nodeId: toDhtAddressRaw(nodeId), - type: isBrowserEnvironment() ? NodeType.BROWSER : NodeType.NODEJS, + type: isBrowserEnvironment ? NodeType.BROWSER : NodeType.NODEJS, ipAddress: ipv4ToNumber(IP_ADDRESS), publicKey: expect.any(Uint8Array), signature: expect.any(Uint8Array), diff --git a/packages/dht/test/unit/getClosestNodes.test.ts b/packages/dht/test/unit/getClosestNodes.test.ts index f69003cb9e..4b196dc68f 100644 --- a/packages/dht/test/unit/getClosestNodes.test.ts +++ b/packages/dht/test/unit/getClosestNodes.test.ts @@ -1,11 +1,11 @@ import range from 'lodash/range' import sampleSize from 'lodash/sampleSize' import sortBy from 'lodash/sortBy' -import { getDistance } from '../../src/dht/PeerManager' +import { getPeerDistance } from '../../src/dht/helpers/getPeerDistance' import { getClosestNodes } from '../../src/dht/contact/getClosestNodes' import { DhtAddress, randomDhtAddress, toNodeId, toDhtAddressRaw } from '../../src/identifiers' import { createMockPeerDescriptor } from '../utils/utils' -import { PeerDescriptor } from '../../src/exports' +import { PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' describe('getClosestNodes', () => { @@ -25,7 +25,7 @@ describe('getClosestNodes', () => { const expected = sortBy( peerDescriptors.filter((n) => !excluded.has(toNodeId(n))), - (peerDescriptor: PeerDescriptor) => getDistance(peerDescriptor.nodeId, toDhtAddressRaw(referenceId)) + (peerDescriptor: PeerDescriptor) => getPeerDistance(peerDescriptor.nodeId, toDhtAddressRaw(referenceId)) ).slice(0, 5) expect(actual).toEqual(expected) }) diff --git a/packages/dht/test/utils/FakeTransport.ts b/packages/dht/test/utils/FakeTransport.ts index c5796c153e..f736362826 100644 --- a/packages/dht/test/utils/FakeTransport.ts +++ b/packages/dht/test/utils/FakeTransport.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3' import { DhtAddress, toDhtAddress, toNodeId } from '../../src/identifiers' import { Message, PeerDescriptor } from '../../generated/packages/dht/protos/DhtRpc' import { DEFAULT_SEND_OPTIONS, ITransport, SendOptions, TransportEvents } from '../../src/transport/ITransport' -import { ConnectionsView } from '../../src/exports' +import { ConnectionsView } from '../../src/connection/ConnectionsView' // TODO extract ConnectionsView functionality to FakeConnectionsView class FakeTransport extends EventEmitter implements ITransport, ConnectionsView { diff --git a/packages/dht/test/utils/mock/MockConnection.ts b/packages/dht/test/utils/mock/MockConnection.ts index 126789ef5b..d84b5d1770 100644 --- a/packages/dht/test/utils/mock/MockConnection.ts +++ b/packages/dht/test/utils/mock/MockConnection.ts @@ -1,4 +1,4 @@ -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { ConnectionEvents, IConnection } from '../../../src/connection/IConnection' export class MockConnection extends EventEmitter implements IConnection { diff --git a/packages/dht/test/utils/topology.ts b/packages/dht/test/utils/topology.ts index 4215a7842a..3f69460128 100644 --- a/packages/dht/test/utils/topology.ts +++ b/packages/dht/test/utils/topology.ts @@ -4,7 +4,7 @@ import minBy from 'lodash/minBy' import range from 'lodash/range' import without from 'lodash/without' import { SortedContactList } from '../../src/dht/contact/SortedContactList' -import { getDistance } from '../../src/dht/PeerManager' +import { getPeerDistance } from '../../src/dht/helpers/getPeerDistance' export const getTopologyPartitions = (topology: Multimap): Set[] => { let partitions: Set[] = [] @@ -72,7 +72,7 @@ export const createTestTopology = (nodeCount: number, minNeighorCount: number): const closestNodedId = getClosestNodes(nodeId, otherNodes, 1, false)[0] return [nodeId, closestNodedId] }) - const mergePair = minBy(closestPairs, (pair) => getDistance(toDhtAddressRaw(pair[0]), toDhtAddressRaw(pair[1])))! + const mergePair = minBy(closestPairs, (pair) => getPeerDistance(toDhtAddressRaw(pair[0]), toDhtAddressRaw(pair[1])))! topology.add(mergePair[0], mergePair[1]) topology.add(mergePair[1], mergePair[0]) } diff --git a/packages/dht/tsconfig.browser-generated.json b/packages/dht/tsconfig.browser-generated.json new file mode 100644 index 0000000000..69e11fa259 --- /dev/null +++ b/packages/dht/tsconfig.browser-generated.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.browser.json", + "compilerOptions": { + "noImplicitOverride": false + }, + "include": [ + "generated" + ], + "exclude": [] +} diff --git a/packages/dht/tsconfig.browser.json b/packages/dht/tsconfig.browser.json new file mode 100644 index 0000000000..9b498b4bbd --- /dev/null +++ b/packages/dht/tsconfig.browser.json @@ -0,0 +1,44 @@ +{ + "extends": "../../tsconfig.browser.json", + "compilerOptions": { + "outDir": "dist/browser", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/browser/*" + ] + }, + + /* @todo Make verbatimModuleSyntax (true) work. */ + "verbatimModuleSyntax": false, + + /* @todo Make useUnknownInCatchVariables (true) work. */ + "useUnknownInCatchVariables": false, + + /* @todo Make erasableSyntaxOnly (true) work. */ + "erasableSyntaxOnly": false, + + /* @todo Make noUnusedLocals (true) work. */ + "noUnusedLocals": false, + + /* @todo Make noUnusedParameters (true) work. */ + "noUnusedParameters": false + }, + "include": [ + "src", + "package.json" + ], + "exclude": [ + "src/nodejs" + ], + "references": [ + { "path": "../utils" }, + { "path": "../proto-rpc" }, + { "path": "../cdn-location" }, + { "path": "../geoip-location" }, + { "path": "../autocertifier-client" }, + { "path": "./tsconfig.browser-generated.json" } + ] +} diff --git a/packages/dht/tsconfig.jest.json b/packages/dht/tsconfig.jest.json index 033d864c42..e506dbfe70 100644 --- a/packages/dht/tsconfig.jest.json +++ b/packages/dht/tsconfig.jest.json @@ -1,12 +1,24 @@ { "extends": "../../tsconfig.jest.json", + "compilerOptions": { + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/nodejs/*" + ] + } + }, "include": [ "src", "test", - "package.json", - "scripts" + "package.json" + ], + "exclude": [ + "src/browser" ], "references": [ - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node-generated.json" } ] } diff --git a/packages/dht/tsconfig.json b/packages/dht/tsconfig.json index e5441a57dd..9a557a2379 100644 --- a/packages/dht/tsconfig.json +++ b/packages/dht/tsconfig.json @@ -1,18 +1,10 @@ { - "extends": "../../tsconfig.node.json", + "files": [], "compilerOptions": { - "outDir": "dist" + "composite": true }, - "include": [ - "src", - "package.json" - ], "references": [ - { "path": "../utils" }, - { "path": "../proto-rpc" }, - { "path": "../cdn-location" }, - { "path": "../geoip-location" }, - { "path": "../autocertifier-client" }, - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.browser.json" } ] } diff --git a/packages/dht/tsconfig.karma.json b/packages/dht/tsconfig.karma.json index 28bd6d922c..b5fd515e7a 100644 --- a/packages/dht/tsconfig.karma.json +++ b/packages/dht/tsconfig.karma.json @@ -1,10 +1,21 @@ { "extends": "../../tsconfig.karma.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist/karma", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/browser/*" + ] + } }, "include": [ "src", "package.json" - ] + ], + "exclude": [ + "src/nodejs" + ], } diff --git a/packages/dht/tsconfig.generated.json b/packages/dht/tsconfig.node-generated.json similarity index 75% rename from packages/dht/tsconfig.generated.json rename to packages/dht/tsconfig.node-generated.json index 4ce2cee0f2..b57b4a74d3 100644 --- a/packages/dht/tsconfig.generated.json +++ b/packages/dht/tsconfig.node-generated.json @@ -1,5 +1,5 @@ { - "extends": "./tsconfig.json", + "extends": "./tsconfig.node.json", "compilerOptions": { "noImplicitOverride": false }, diff --git a/packages/dht/tsconfig.node.json b/packages/dht/tsconfig.node.json new file mode 100644 index 0000000000..8f9dd4cfbc --- /dev/null +++ b/packages/dht/tsconfig.node.json @@ -0,0 +1,33 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "outDir": "dist/nodejs", + + /* Mapping */ + "paths": { + "@/*": [ + "src/nodejs/*" + ] + }, + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." + }, + "include": [ + "src", + "package.json" + ], + "exclude": [ + "src/browser" + ], + "references": [ + { "path": "../utils" }, + { "path": "../proto-rpc" }, + { "path": "../cdn-location" }, + { "path": "../geoip-location" }, + { "path": "../autocertifier-client" }, + { "path": "./tsconfig.node-generated.json" } + ] +} diff --git a/packages/geoip-location/package.json b/packages/geoip-location/package.json index 5ee83e0e2c..38b7c3ceab 100644 --- a/packages/geoip-location/package.json +++ b/packages/geoip-location/package.json @@ -1,21 +1,20 @@ { "name": "@streamr/geoip-location", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Library for getting location information from IP addresses based on MaxMind GeoLite2 databases", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/geoip-location" }, - "main": "dist/src/exports.js", + "main": "./dist/exports.cjs", + "module": "./dist/exports.js", + "types": "./dist/exports.d.ts", "browser": { - "dist/src/exports.js": false, - "dist/src/GeoIpLocator.js": false, - "dist/src/downloadGeoIpDatabase.js": false + "./dist/exports.js": false }, - "types": "dist/src/exports.d.ts", "files": [ - "dist", + "dist/exports.*", "!*.tsbuildinfo", "README.md", "LICENSE" @@ -23,15 +22,18 @@ "license": "Apache-2.0", "author": "Streamr Network AG ", "scripts": { + "prebuild": "npm run reset-self", "build": "tsc -b", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -p tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", "test": "jest test/unit", "test-unit": "jest test/unit" }, "dependencies": { - "@streamr/utils": "103.2.0", + "@streamr/utils": "103.2.0-experiment.1", "eventemitter3": "^5.0.0", "long-timeout": "^0.1.1", "mmdb-lib": "^3.0.1", @@ -39,8 +41,13 @@ "uuid": "^11.1.0" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", "@types/long-timeout": "^0.1.2", "@types/tar": "^6.1.11", - "express": "^5.2.0" + "express": "^5.2.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" } } diff --git a/packages/geoip-location/rollup.config.mts b/packages/geoip-location/rollup.config.mts new file mode 100644 index 0000000000..517b0f9b30 --- /dev/null +++ b/packages/geoip-location/rollup.config.mts @@ -0,0 +1,52 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + nodejs(), + nodejsTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { file: './dist/exports.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/geoip-location/tsconfig.json b/packages/geoip-location/tsconfig.json index 5621ed82fc..6ad637ddb1 100644 --- a/packages/geoip-location/tsconfig.json +++ b/packages/geoip-location/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." }, "include": [ "src" diff --git a/packages/node/package.json b/packages/node/package.json index 9a3446a227..6afef75b8c 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@streamr/node", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "A full-featured node implementation for the Streamr Network", "repository": { "type": "git", @@ -39,9 +39,9 @@ "dependencies": { "@inquirer/prompts": "^7.9.0", "@streamr/config": "^5.9.2", - "@streamr/dht": "103.2.0", - "@streamr/sdk": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/dht": "103.2.0-experiment.1", + "@streamr/sdk": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "aedes": "^0.51.3", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", @@ -65,7 +65,7 @@ "devDependencies": { "@inquirer/testing": "^2.1.51", "@streamr/network-contracts": "^9.1.0", - "@streamr/test-utils": "103.2.0", + "@streamr/test-utils": "103.2.0-experiment.1", "@types/cors": "^2.8.19", "@types/express": "^5.0.1", "@types/heap": "^0.2.35", diff --git a/packages/proto-rpc/package.json b/packages/proto-rpc/package.json index a8e0ec204b..7adf4b94b0 100644 --- a/packages/proto-rpc/package.json +++ b/packages/proto-rpc/package.json @@ -1,16 +1,17 @@ { "name": "@streamr/proto-rpc", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Proto-RPC", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/proto-rpc" }, - "main": "dist/src/exports.js", - "types": "dist/src/exports.d.ts", + "main": "./dist/exports.cjs", + "module": "./dist/exports.js", + "types": "./dist/exports.d.ts", "files": [ - "dist", + "dist/exports.*", "!*.tsbuildinfo", "README.md", "LICENSE" @@ -18,10 +19,11 @@ "license": "(Apache-2.0 AND BSD-3-Clause)", "author": "Streamr Network AG ", "scripts": { - "prebuild": "./proto.sh", + "prebuild": "npm run reset-self && ./proto.sh", "build": "tsc -b", - "build-browser": "webpack --mode=development --progress", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "./test-proto.sh && tsc -b tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist generated *.tsbuildinfo node_modules/.cache || true", "eslint": "./test-proto.sh && eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", "test": "./test-proto.sh && npm run test-unit && npm run test-integration", @@ -32,15 +34,20 @@ "dependencies": { "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", - "@streamr/utils": "103.2.0", + "@streamr/utils": "103.2.0-experiment.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", "uuid": "^11.1.0" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", - "@streamr/test-utils": "103.2.0", - "@types/lodash": "^4.17.21" + "@streamr/test-utils": "103.2.0-experiment.1", + "@types/lodash": "^4.17.21", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" }, "optionalDependencies": { "bufferutil": "^4.0.9", diff --git a/packages/proto-rpc/rollup.config.mts b/packages/proto-rpc/rollup.config.mts new file mode 100644 index 0000000000..517b0f9b30 --- /dev/null +++ b/packages/proto-rpc/rollup.config.mts @@ -0,0 +1,52 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + nodejs(), + nodejsTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports.cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { file: './dist/exports.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/proto-rpc/tsconfig.json b/packages/proto-rpc/tsconfig.json index 9bb9cf3b51..be7119ed21 100644 --- a/packages/proto-rpc/tsconfig.json +++ b/packages/proto-rpc/tsconfig.json @@ -1,7 +1,12 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + + /* Resolution */ + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": "." }, "include": [ "src" diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 79a1bce3bd..3d76cac685 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@streamr/sdk", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "JavaScript / TypeScript SDK for Streamr", "repository": { "type": "git", @@ -60,7 +60,7 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", - "@streamr/test-utils": "103.2.0", + "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/lodash": "^4.17.21", "ajv": "^8.17.1", @@ -98,11 +98,11 @@ "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", "@streamr/config": "^5.9.2", - "@streamr/dht": "103.2.0", + "@streamr/dht": "103.2.0-experiment.1", "@streamr/network-contracts": "^9.1.0", - "@streamr/proto-rpc": "103.2.0", - "@streamr/trackerless-network": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/proto-rpc": "103.2.0-experiment.1", + "@streamr/trackerless-network": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "core-js": "^3.47.0", "env-paths": "^2.2.1", "ethers": "^6.13.0", diff --git a/packages/sdk/test/types/global.d.ts b/packages/sdk/test/types/global.d.ts index 3d154612b2..a0c38efe3f 100644 --- a/packages/sdk/test/types/global.d.ts +++ b/packages/sdk/test/types/global.d.ts @@ -1,2 +1,2 @@ import 'jest-extended' -import '@streamr/test-utils/customMatcherTypes' +import '@streamr/test-utils/customMatchers' diff --git a/packages/test-utils/customMatcherTypes.d.ts b/packages/test-utils/customMatcherTypes.d.ts deleted file mode 100644 index 6e4effea9e..0000000000 --- a/packages/test-utils/customMatcherTypes.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This file injects custom matcher types into Jest. - * - * The actual type declarations are in "./dist/src/customMatcherTypes.d.ts", and this file serves - * as an alias. In a dependent library the type information is typically injected by adding - * an import statement to test/types/global.d.ts. Since this file is listed in package.json's - * "files" section, we can import the types like this: - * import '@streamr/test-utils/customMatcherTypes' - */ - -/// diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 1465ce1a1a..53f0ba2e50 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,23 +1,61 @@ { "name": "@streamr/test-utils", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "A collection of shared test utilities", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/test-utils" }, - "main": "./dist/src/index.js", - "types": "./dist/src/index.d.ts", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "node": "./dist/index.cjs", + "import": "./dist/index.js", + "require": "./dist/index.cjs", + "default": "./dist/index.js" + }, + "./setupCustomMatchers": { + "types": "./dist/setupCustomMatchers.d.ts", + "node": "./dist/setupCustomMatchers.cjs", + "import": "./dist/setupCustomMatchers.js", + "require": "./dist/setupCustomMatchers.cjs", + "default": "./dist/setupCustomMatchers.js" + }, + "./customMatchers": { + "types": "./dist/customMatchers.d.ts", + "node": "./dist/customMatchers.cjs", + "import": "./dist/customMatchers.js", + "require": "./dist/customMatchers.cjs", + "default": "./dist/customMatchers.js" + } + }, + "typesVersions": { + "*": { + "customMatchers": [ + "dist/customMatchers.d.ts" + ], + "setupCustomMatchers": [ + "dist/setupCustomMatchers.d.ts" + ] + } + }, "files": [ "dist", + "!dist/src", "!*.tsbuildinfo", - "setupCustomMatchers.js", - "customMatcherTypes.d.ts" + "LICENSE", + "README.md" ], "scripts": { + "prebuild": "npm run reset-self", "build": "tsc -b", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -p tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist *.tsbuildinfo node_modules/.cache || true", "test": "jest", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'" @@ -27,7 +65,7 @@ "dependencies": { "@streamr/config": "^5.9.2", "@streamr/network-contracts": "^9.1.0", - "@streamr/utils": "103.2.0", + "@streamr/utils": "103.2.0-experiment.1", "cors": "^2.8.5", "ethers": "^6.13.0", "express": "^5.2.0", @@ -36,7 +74,12 @@ "lodash": "^4.17.21" }, "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", "@types/cors": "^2.8.19", - "@types/express": "^5.0.1" + "@types/express": "^5.0.1", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" } } diff --git a/packages/test-utils/rollup.config.mts b/packages/test-utils/rollup.config.mts new file mode 100644 index 0000000000..efde0221cc --- /dev/null +++ b/packages/test-utils/rollup.config.mts @@ -0,0 +1,99 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default defineConfig([ + nodejs(), + ...nodejsTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: [ + './dist/src/index.js', + './dist/src/customMatchers.js', + './dist/src/setupCustomMatchers.js', + ], + output: [ + { + format: 'es', + dir: './dist', + entryFileNames: '[name].js', + chunkFileNames: '[name].[hash].js', + sourcemap: true, + }, + { + format: 'cjs', + dir: './dist', + entryFileNames: '[name].cjs', + chunkFileNames: '[name].[hash].cjs', + sourcemap: true, + }, + ], + plugins: [ + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions[] { + return [ + { + input: './dist/src/index.d.ts', + output: [ + { file: './dist/index.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + }, + { + input: './dist/src/customMatchers.d.ts', + output: [ + { file: './dist/customMatchers.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + }, + { + input: './dist/src/setupCustomMatchers.d.ts', + output: [ + { file: './dist/setupCustomMatchers.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + onwarn(warning, rollupWarn) { + /** + * setupCustomMatchers.d.ts is an empty file, so rollup dts plugin + * generates an EMPTY_BUNDLE warning. We can safely ignore it. + */ + if (warning.code !== 'EMPTY_BUNDLE') { + rollupWarn(warning) + } + } + } + ] +} diff --git a/packages/test-utils/setupCustomMatchers.js b/packages/test-utils/setupCustomMatchers.js deleted file mode 100644 index d9832f05f7..0000000000 --- a/packages/test-utils/setupCustomMatchers.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file adds the custom matcher functionality to Jest. - * - * The actual setup is in "./dist/src/setupCustomMatchers.js", and this file serves as an alias. - * Since this file is listed in package.json's "files" section, we can setup the custom matchers - * like this: - * setupFilesAfterEnv: ['@streamr/test-utils/setupCustomMatchers'] - */ - -require('./dist/src/setupCustomMatchers') diff --git a/packages/test-utils/src/customMatcherTypes.ts b/packages/test-utils/src/customMatcherTypes.ts deleted file mode 100644 index 90b0653dc6..0000000000 --- a/packages/test-utils/src/customMatcherTypes.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CustomMatchers } from './customMatchers' - -// we could ES2015 module syntax (https://jestjs.io/docs/expect#expectextendmatchers), -// but the IDE doesn't find custom matchers if we do that -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace jest { - // eslint-disable-next-line @typescript-eslint/no-empty-object-type - interface Expect extends CustomMatchers {} - // eslint-disable-next-line @typescript-eslint/no-empty-object-type - interface Matchers extends CustomMatchers {} - } -} diff --git a/packages/test-utils/src/customMatchers.ts b/packages/test-utils/src/customMatchers.ts index ea67328cec..075c570f48 100644 --- a/packages/test-utils/src/customMatchers.ts +++ b/packages/test-utils/src/customMatchers.ts @@ -47,4 +47,22 @@ const toEqualBinary = ( } } -export { toEqualBinary } +export const customMatchers = { + toEqualBinary +} + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface Matchers extends CustomMatchers {} + } +} + +declare module 'expect' { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface AsymmetricMatchers extends CustomMatchers {} + + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface Matchers extends CustomMatchers {} +} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts index e6cc6958b5..3ad11e5639 100644 --- a/packages/test-utils/src/index.ts +++ b/packages/test-utils/src/index.ts @@ -176,8 +176,7 @@ type MethodNames = { // Pick only methods of T export type Methods = Pick> -import * as customMatchers from './customMatchers' -export { customMatchers } +export { customMatchers } from './customMatchers' const TEST_CHAIN_CONFIG = CHAIN_CONFIG.dev2 diff --git a/packages/test-utils/src/setupCustomMatchers.ts b/packages/test-utils/src/setupCustomMatchers.ts index d2479902d0..3f6b11f567 100644 --- a/packages/test-utils/src/setupCustomMatchers.ts +++ b/packages/test-utils/src/setupCustomMatchers.ts @@ -1,3 +1,2 @@ -import * as customMatchers from './customMatchers' - +import { customMatchers } from './customMatchers' expect.extend(customMatchers) diff --git a/packages/test-utils/test/customMatchers.test.ts b/packages/test-utils/test/customMatchers.test.ts index 985b54cb2b..51388e96f5 100644 --- a/packages/test-utils/test/customMatchers.test.ts +++ b/packages/test-utils/test/customMatchers.test.ts @@ -1,4 +1,4 @@ -import {} from '../src/customMatcherTypes' +import '../src/customMatchers' describe('custom matchers', () => { it('happy path', () => { diff --git a/packages/test-utils/tsconfig.json b/packages/test-utils/tsconfig.json index 33cb004949..bc8bf7329e 100644 --- a/packages/test-utils/tsconfig.json +++ b/packages/test-utils/tsconfig.json @@ -5,7 +5,11 @@ "types": [ "node", "jest" - ] + ], + + /* Resolution */ + "moduleResolution": "bundler", + "module": "preserve" }, "include": [ "src" diff --git a/packages/trackerless-network/karma.config.ts b/packages/trackerless-network/karma.config.ts index 4d2fb6f2be..e7779dfd9e 100644 --- a/packages/trackerless-network/karma.config.ts +++ b/packages/trackerless-network/karma.config.ts @@ -10,12 +10,11 @@ const TEST_PATHS = [ export default createKarmaConfig(TEST_PATHS, createWebpackConfig({ libraryName: 'trackerless-network', alias: { - [resolve(__dirname, '../dht/src/connection/webrtc/NodeWebrtcConnection.ts')]: - resolve(__dirname, '../dht/src/connection/webrtc/BrowserWebrtcConnection.ts'), - [resolve(__dirname, '../dht/src/connection/websocket/NodeWebsocketClientConnection.ts')]: - resolve(__dirname, '../dht/src/connection/websocket/BrowserWebsocketClientConnection.ts'), - '@streamr/dht': resolve('../dht/src/exports.ts'), - '@streamr/proto-rpc': resolve('../proto-rpc/src/exports.ts'), + /** + * @todo Our "browser" tests use the Node.js build of DHT package – needed + * for WebSocket/Simulator stuff, but still, very confusing. + */ + '@streamr/dht': resolve(__dirname, '../dht/dist/exports-nodejs.cjs'), }, fallback: { module: false diff --git a/packages/trackerless-network/package.json b/packages/trackerless-network/package.json index 35fdda4c22..8dabcd40b1 100644 --- a/packages/trackerless-network/package.json +++ b/packages/trackerless-network/package.json @@ -1,26 +1,28 @@ { "name": "@streamr/trackerless-network", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "Minimal and extendable implementation of the Streamr Network node.", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network-monorepo.git", "directory": "packages/trackerless-network" }, - "main": "dist/src/exports.js", - "types": "dist/src/exports.d.ts", + "main": "./dist/exports.cjs", + "module": "./dist/exports.js", + "types": "./dist/exports.d.ts", "files": [ - "dist", + "dist/exports.*", "!*.tsbuildinfo", "README.md" ], "license": "STREAMR NETWORK OPEN SOURCE LICENSE", "author": "Streamr Network AG ", "scripts": { + "prebuild": "npm run reset-self && ./proto.sh", "build": "tsc -b", - "build-browser": "webpack --mode=development --progress", - "prebuild": "./proto.sh", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -b tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist generated *.tsbuildinfo node_modules/.cache || true", "coverage": "jest --coverage", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", @@ -35,9 +37,9 @@ "dependencies": { "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", - "@streamr/dht": "103.2.0", - "@streamr/proto-rpc": "103.2.0", - "@streamr/utils": "103.2.0", + "@streamr/dht": "103.2.0-experiment.1", + "@streamr/proto-rpc": "103.2.0-experiment.1", + "@streamr/utils": "103.2.0-experiment.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", "ts-essentials": "^10.1.1", @@ -45,11 +47,17 @@ "yallist": "^5.0.0" }, "devDependencies": { + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", - "@streamr/test-utils": "103.2.0", + "@streamr/test-utils": "103.2.0-experiment.1", "@types/lodash": "^4.17.21", "@types/yallist": "^5.0.0", "expect": "^30.0.5", - "ts-node": "^10.9.2" + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "ts-node": "^10.9.2", + "tsx": "^4.21.0" } } diff --git a/packages/trackerless-network/rollup.config.mts b/packages/trackerless-network/rollup.config.mts new file mode 100644 index 0000000000..7c9b709e26 --- /dev/null +++ b/packages/trackerless-network/rollup.config.mts @@ -0,0 +1,54 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import json from '@rollup/plugin-json' + +export default defineConfig([ + nodejs(), + nodejsTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports.cjs', + sourcemap: true, + }, + ], + plugins: [ + json(), + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/exports.d.ts', + output: [ + { file: './dist/exports.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/trackerless-network/src/ContentDeliveryManager.ts b/packages/trackerless-network/src/ContentDeliveryManager.ts index 7b8a48b12d..81d98697f6 100644 --- a/packages/trackerless-network/src/ContentDeliveryManager.ts +++ b/packages/trackerless-network/src/ContentDeliveryManager.ts @@ -10,6 +10,7 @@ import { toNodeId } from '@streamr/dht' import { + computeSha1, Logger, Metric, MetricsContext, @@ -18,7 +19,6 @@ import { UserID, toStreamPartID } from '@streamr/utils' -import { createHash } from 'crypto' import { EventEmitter } from 'eventemitter3' import sampleSize from 'lodash/sampleSize' import { ProxyDirection, StreamMessage } from '../generated/packages/trackerless-network/protos/NetworkRpc' @@ -85,7 +85,7 @@ export interface StreamPartDeliveryOptions { } export const streamPartIdToDataKey = (streamPartId: StreamPartID): DhtAddress => { - return toDhtAddress(new Uint8Array((createHash('sha1').update(streamPartId).digest()))) + return toDhtAddress(computeSha1(streamPartId)) } export class ContentDeliveryManager extends EventEmitter { diff --git a/packages/trackerless-network/src/NetworkStack.ts b/packages/trackerless-network/src/NetworkStack.ts index a6d2601359..4198d0481c 100644 --- a/packages/trackerless-network/src/NetworkStack.ts +++ b/packages/trackerless-network/src/NetworkStack.ts @@ -32,19 +32,47 @@ const stopInstances = async () => { const clonedInstances = [...instances] await Promise.all(clonedInstances.map((instance) => instance.stop())) } -const EXIT_EVENTS = [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `unhandledRejection`, `SIGTERM`] -EXIT_EVENTS.forEach((event) => { - process.on(event, async (eventArg) => { - const isError = (event === 'uncaughtException') || (event === 'unhandledRejection') - if (isError) { - logger.error(`exit event: ${event}`, eventArg) - } - await stopInstances() - process.exit(isError ? 1 : 0) + +/** + * @todo The following cleanup logic is currently handled inside this module for both Node.js and + * browser environments. Consider refactoring it into a higher-level integration layer if lifecycle + * management is centralized elsewhere. + */ +if (typeof process === 'object' && typeof process?.on === 'function') { + /** + * @todo The `exit` event shouldn't use an async handler because the event loop is already + * shutting down, so async work won't complete. Calling `process.exit()` inside an `exit` + * handler is also redundant and may cause issues. Remove `exit` from `EXIT_EVENTS` + * or omit it entirely, since other signal handlers already terminate the process. + */ + const EXIT_EVENTS = [`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `unhandledRejection`, `SIGTERM`] + EXIT_EVENTS.forEach((event) => { + /** + * @todo Registering handlers at module load time can cause side effects. Use explicit + * or lazy initialization to improve control and testability. + */ + process.on(event, async (eventArg) => { + const isError = (event === 'uncaughtException') || (event === 'unhandledRejection') + if (isError) { + logger.error(`exit event: ${event}`, eventArg) + } + /** + * @todo Async `stopInstances()` may be interrupted by `process.exit()`. Use + * synchronous cleanup or a timeout, and wait for cleanup on graceful signals + * but exit quickly on error events. + */ + await stopInstances() + process.exit(isError ? 1 : 0) + }) }) -}) +} + declare let window: any if (typeof window === 'object') { + /** + * @todo Registering handlers at module load time can cause side effects. Use explicit + * or lazy initialization to improve control and testability. + */ window.addEventListener('unload', async () => { await stopInstances() }) diff --git a/packages/trackerless-network/src/content-delivery-layer/plumtree/PlumtreeManager.ts b/packages/trackerless-network/src/content-delivery-layer/plumtree/PlumtreeManager.ts index 27bc9ef607..a38b0d2e1f 100644 --- a/packages/trackerless-network/src/content-delivery-layer/plumtree/PlumtreeManager.ts +++ b/packages/trackerless-network/src/content-delivery-layer/plumtree/PlumtreeManager.ts @@ -9,7 +9,7 @@ import { NodeList } from '../NodeList' import { PlumtreeRpcLocal } from './PlumtreeRpcLocal' import { PlumtreeRpcRemote } from './PlumtreeRpcRemote' import { ContentDeliveryRpcClient, PlumtreeRpcClient } from '../../../generated/packages/trackerless-network/protos/NetworkRpc.client' -import EventEmitter from 'eventemitter3' +import { EventEmitter } from 'eventemitter3' import { Logger } from '@streamr/utils' import { ContentDeliveryRpcRemote } from '../ContentDeliveryRpcRemote' import { PausedNeighbors } from './PausedNeighbors' diff --git a/packages/trackerless-network/tsconfig.generated.json b/packages/trackerless-network/tsconfig.generated.json index 4ce2cee0f2..b57b4a74d3 100644 --- a/packages/trackerless-network/tsconfig.generated.json +++ b/packages/trackerless-network/tsconfig.generated.json @@ -1,5 +1,5 @@ { - "extends": "./tsconfig.json", + "extends": "./tsconfig.node.json", "compilerOptions": { "noImplicitOverride": false }, diff --git a/packages/trackerless-network/tsconfig.json b/packages/trackerless-network/tsconfig.json index 0933004e01..667d1ae42d 100644 --- a/packages/trackerless-network/tsconfig.json +++ b/packages/trackerless-network/tsconfig.json @@ -1,16 +1,9 @@ { - "extends": "../../tsconfig.node.json", + "files": [], "compilerOptions": { - "outDir": "dist" + "composite": true }, - "include": [ - "src", - "package.json" - ], "references": [ - { "path": "../utils" }, - { "path": "../proto-rpc" }, - { "path": "../dht" }, - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node.json" } ] } diff --git a/packages/trackerless-network/tsconfig.node.json b/packages/trackerless-network/tsconfig.node.json new file mode 100644 index 0000000000..abc81532e1 --- /dev/null +++ b/packages/trackerless-network/tsconfig.node.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "outDir": "dist", + + /* Resolution */ + "moduleResolution": "bundler", + "module": "preserve" + }, + "include": [ + "src", + "package.json" + ], + "references": [ + { "path": "../utils" }, + { "path": "../proto-rpc" }, + { "path": "../dht" }, + { "path": "./tsconfig.generated.json" } + ] +} diff --git a/packages/utils/jest.config.ts b/packages/utils/jest.config.ts index 550da64839..18301ec7c1 100644 --- a/packages/utils/jest.config.ts +++ b/packages/utils/jest.config.ts @@ -1 +1,11 @@ -export { default } from '../../jest.config' +import type { Config } from "@jest/types" +import defaultConfig from "../../jest.config" + +const config: Config.InitialOptions = { + ...defaultConfig, + moduleNameMapper: { + "^@/(.*)$": "/src/nodejs/$1", + }, +} + +export default config diff --git a/packages/utils/karma.config.ts b/packages/utils/karma.config.ts index 79cb15a828..8929fae25f 100644 --- a/packages/utils/karma.config.ts +++ b/packages/utils/karma.config.ts @@ -1,4 +1,5 @@ import { createKarmaConfig, createWebpackConfig } from '@streamr/browser-test-runner' +import { resolve } from 'path' const TEST_PATHS = ['test/**/*.ts'] @@ -6,5 +7,10 @@ export default createKarmaConfig(TEST_PATHS, createWebpackConfig({ libraryName: 'utils', fallback: { module: false - } + }, + alias: { + '@': resolve(__dirname, 'src/browser'), + os: resolve(__dirname, 'src/browser/os.ts'), + path: 'path-browserify', + }, })) diff --git a/packages/utils/package.json b/packages/utils/package.json index 391dd6d446..ac268963aa 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,23 +1,43 @@ { "name": "@streamr/utils", - "version": "103.2.0", + "version": "103.2.0-experiment.1", "description": "A collection of shared common utilities", "repository": { "type": "git", "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/utils" }, - "main": "./dist/src/exports.js", - "types": "./dist/src/exports.d.ts", + "main": "./dist/exports-nodejs.cjs", + "module": "./dist/exports-nodejs.js", + "types": "./dist/exports-nodejs.d.ts", + "exports": { + ".": { + "types": "./dist/exports-nodejs.d.ts", + "browser": { + "types": "./dist/exports-browser.d.ts", + "import": "./dist/exports-browser.js", + "require": "./dist/exports-browser.cjs", + "default": "./dist/exports-browser.js" + }, + "node": "./dist/exports-nodejs.cjs", + "import": "./dist/exports-nodejs.js", + "require": "./dist/exports-nodejs.cjs", + "default": "./dist/exports-nodejs.js" + } + }, "files": [ - "dist", + "dist/exports-nodejs.*", + "dist/exports-browser.*", "!*.tsbuildinfo", "README.md", "LICENSE" ], "scripts": { + "prebuild": "npm run reset-self", "build": "tsc -b", - "check": "tsc -p tsconfig.jest.json", + "postbuild": "NODE_OPTIONS=\"--import tsx\" rollup -c rollup.config.mts", + "check": "tsc -b tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts}'", "test": "jest", @@ -27,17 +47,35 @@ "license": "Apache-2.0", "dependencies": { "@noble/curves": "^1.9.7", + "@noble/hashes": "^2.0.1", "@noble/post-quantum": "^0.4.1", + "browserify-aes": "^1.2.0", + "buffer": "^6.0.3", + "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", + "md5": "^2.3.0", + "md5.js": "^1.3.5", + "path-browserify": "^1.0.1", "pino": "^10.1.0", "pino-pretty": "^13.1.2", + "readable-stream": "^4.7.0", "secp256k1": "^5.0.1", "sha3": "^2.1.4" }, "devDependencies": { + "@rollup/plugin-alias": "^6.0.0", + "@rollup/plugin-commonjs": "^29.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/browser-test-runner": "^0.0.1", "@types/lodash": "^4.17.21", - "@types/secp256k1": "^4.0.7" + "@types/md5": "^2.3.6", + "@types/readable-stream": "^4.0.23", + "@types/secp256k1": "^4.0.7", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-dts": "^6.3.0", + "tsx": "^4.21.0" } } diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts new file mode 100644 index 0000000000..ed7ba94871 --- /dev/null +++ b/packages/utils/rollup.config.mts @@ -0,0 +1,165 @@ +import { defineConfig, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import alias, { type Alias } from '@rollup/plugin-alias' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import cjs from '@rollup/plugin-commonjs' +import json from '@rollup/plugin-json' +import { fileURLToPath } from 'node:url' + +const nodejsAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/nodejs/src/nodejs/', import.meta.url) + ), + }, +] + +const browserAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/browser/src/browser/', import.meta.url) + ), + }, + { + find: 'os', + replacement: fileURLToPath( + new URL('./dist/browser/src/browser/os.js', import.meta.url) + ), + }, + { + find: 'path', + replacement: 'path-browserify', + }, + { + find: 'stream', + replacement: 'readable-stream', + }, + { + find: /^pino$/, + replacement: 'pino/browser', + }, +] + +export default defineConfig([ + nodejs(), + nodejsTypes(), + browser(), + browserTypes(), +]) + +function nodejs(): RollupOptions { + return { + input: './dist/nodejs/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-nodejs.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-nodejs.cjs', + sourcemap: true, + }, + ], + plugins: [ + alias({ + entries: nodejsAliases, + }), + nodeResolve({ + preferBuiltins: true, + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browser(): RollupOptions { + return { + input: './dist/browser/src/exports-browser.js', + output: [ + { + format: 'es', + file: './dist/exports-browser.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-browser.cjs', + sourcemap: true, + }, + ], + plugins: [ + alias({ + entries: browserAliases, + }), + cjs(), + json(), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + ], + external: [ + /** + * We need to bundle some dependencies in. This will make sure we use the local `md5.js` + * and not the one shipped with `create-hash` (which is outdated and has issues with + * modern bundlers). + */ + /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base)/, + /@streamr\//, + ], + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/nodejs/src/exports.d.ts', + output: [ + { + file: './dist/exports-nodejs.d.ts', + }, + ], + plugins: [ + alias({ + entries: nodejsAliases, + }), + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browserTypes(): RollupOptions { + return { + input: './dist/browser/src/exports-browser.d.ts', + output: [ + { + file: './dist/exports-browser.d.ts', + }, + ], + plugins: [ + alias({ + entries: browserAliases, + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} diff --git a/packages/utils/src/Logger.ts b/packages/utils/src/Logger.ts index 4fa44199db..1c3d43efb8 100644 --- a/packages/utils/src/Logger.ts +++ b/packages/utils/src/Logger.ts @@ -2,6 +2,7 @@ import pino from 'pino' import path from 'path' import without from 'lodash/without' import padEnd from 'lodash/padEnd' +import { env } from '@/env' export type LogLevel = 'silent' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' @@ -18,44 +19,17 @@ const parseBoolean = (value: string | undefined) => { } } -declare let window: any - /** - * Disabled when in browser or when environment variable DISABLE_PRETTY_LOG is set to true. + * Disabled when environment variable DISABLE_PRETTY_LOG is set to true. */ function isPrettyPrintDisabled(): boolean { - return typeof window === 'object' || (parseBoolean(process.env.DISABLE_PRETTY_LOG) ?? false) + return parseBoolean(env.DISABLE_PRETTY_LOG) ?? false } function isJestRunning(): boolean { - return process.env.JEST_WORKER_ID !== undefined + return env.JEST_WORKER_ID !== undefined } -const rootLogger = pino({ - name: 'rootLogger', - enabled: !process.env.NOLOG, - level: process.env.LOG_LEVEL ?? 'info', - formatters: { - level: (label) => { - return { level: label } // log level as string instead of number - } - }, - transport: isPrettyPrintDisabled() ? undefined : { - target: 'pino-pretty', - options: { - colorize: parseBoolean(process.env.LOG_COLORS) ?? true, - singleLine: true, - translateTime: 'yyyy-mm-dd"T"HH:MM:ss.l', - ignore: 'pid,hostname', - levelFirst: true, - sync: isJestRunning(), - }, - }, - browser: { - asObject: true - } -}) - /** * This whole monstrosity exists only because pino in browser environment will not print a log message * when invoking `logger.info(undefined, 'msg') instead you need to call `logger.info(msg)`. @@ -77,6 +51,39 @@ export type LoggerModule = string | { id: string } export class Logger { static NAME_LENGTH = 25 + private static rootLogger: pino.Logger | undefined + + private static getRootLogger(): pino.Logger { + Logger.rootLogger ??= pino({ + name: 'rootLogger', + enabled: !env.NOLOG, + level: env.LOG_LEVEL ?? 'info', + formatters: { + level: (label) => { + return { level: label } // log level as string instead of number + }, + }, + transport: isPrettyPrintDisabled() + ? undefined + : { + target: 'pino-pretty', + options: { + colorize: parseBoolean(env.LOG_COLORS) ?? true, + singleLine: true, + translateTime: 'yyyy-mm-dd"T"HH:MM:ss.l', + ignore: 'pid,hostname', + levelFirst: true, + sync: isJestRunning(), + }, + }, + browser: { + asObject: true, + }, + }) + + return Logger.rootLogger + } + private readonly logger: pino.Logger fatal: (msg: string, metadata?: Record) => void error: (msg: string, metadata?: Record) => void @@ -89,13 +96,13 @@ export class Logger { loggerModule: LoggerModule, contextBindings?: Record, defaultLogLevel: LogLevel = 'info', - parentLogger: pino.Logger = rootLogger + parentLogger: pino.Logger = Logger.getRootLogger() ) { this.logger = parentLogger.child({ name: Logger.createName(loggerModule), ...contextBindings }, { - level: process.env.LOG_LEVEL ?? defaultLogLevel + level: env.LOG_LEVEL ?? defaultLogLevel }) this.fatal = wrappedMethodCall(this.logger.fatal.bind(this.logger)) this.error = wrappedMethodCall(this.logger.error.bind(this.logger)) @@ -114,7 +121,7 @@ export class Logger { const parts = parsedPath.dir.split(path.sep) fileId = parts[parts.length - 1] } - const longName = without([process.env.STREAMR_APPLICATION_ID, fileId], undefined).join(':') + const longName = without([env.STREAMR_APPLICATION_ID, fileId], undefined).join(':') return isPrettyPrintDisabled() ? longName : padEnd(longName.substring(0, this.NAME_LENGTH), this.NAME_LENGTH, ' ') } diff --git a/packages/utils/src/SigningUtil.ts b/packages/utils/src/SigningUtil.ts index 23104621d0..2a664f2a8f 100644 --- a/packages/utils/src/SigningUtil.ts +++ b/packages/utils/src/SigningUtil.ts @@ -6,8 +6,7 @@ import { randomBytes } from '@noble/post-quantum/utils' import { p256 } from '@noble/curves/p256' import { areEqualBinaries, binaryToHex } from './binaryUtils' import type { UserIDRaw } from './UserID' -import { getSubtle } from './crossPlatformCrypto' -import type { webcrypto } from 'crypto' +import { type CryptoKey, getSubtle, type Jwk } from '@/crypto' export const KEY_TYPES = [ 'ECDSA_SECP256K1_EVM', @@ -18,9 +17,6 @@ export const KEY_TYPES = [ export type KeyType = typeof KEY_TYPES[number] const ECDSA_SECP256K1_EVM_SIGN_MAGIC = '\u0019Ethereum Signed Message:\n' -const keccak = new Keccak(256) - -const subtleCrypto = getSubtle() export interface KeyPair { publicKey: Uint8Array @@ -35,11 +31,16 @@ export abstract class SigningUtil { abstract assertValidKeyPair(publicKey: UserIDRaw, privateKey: Uint8Array): void static getInstance(type: KeyType): SigningUtil { - const util = keyTypeToInstance[type] - if (!util) { - throw new Error(`Unknown key pair type: ${type}`) + switch (type) { + case 'ECDSA_SECP256K1_EVM': + return new EcdsaSecp256k1Evm() + case 'ECDSA_SECP256R1': + return new EcdsaSecp256r1() + case 'ML_DSA_87': + return new MlDsa87() + default: + throw new Error(`Unknown key pair type: ${type}`) } - return util } } @@ -58,7 +59,7 @@ export class EcdsaSecp256k1Evm extends SigningUtil { } keccakHash(message: Uint8Array, useEthereumMagic: boolean = true): Buffer { - keccak.reset() + const keccak = new Keccak(256) keccak.update(useEthereumMagic ? Buffer.concat([ Buffer.from(ECDSA_SECP256K1_EVM_SIGN_MAGIC + message.length), message @@ -91,7 +92,7 @@ export class EcdsaSecp256k1Evm extends SigningUtil { throw new Error(`Expected 65 bytes (an ECDSA uncompressed public key with header byte). Got length: ${publicKey.length}`) } const pubKeyWithoutFirstByte = publicKey.subarray(1, publicKey.length) - keccak.reset() + const keccak = new Keccak(256) keccak.update(Buffer.from(pubKeyWithoutFirstByte)) const hashOfPubKey = keccak.digest('binary') return hashOfPubKey.subarray(12, hashOfPubKey.length) @@ -167,7 +168,7 @@ export class EcdsaSecp256r1 extends SigningUtil { throw new Error(`Unexpected public key length: ${publicKey.length}`) } - privateKeyToJWK(privateKey: Uint8Array): webcrypto.JsonWebKey { + privateKeyToJWK(privateKey: Uint8Array): Jwk { const publicKey = this.getPublicKeyFromPrivateKey(privateKey, false) // uncompressed publicKey = [header (1 byte), x (32 bytes), y (32 bytes) const x = publicKey.subarray(1, 33) @@ -199,7 +200,9 @@ export class EcdsaSecp256r1 extends SigningUtil { * Pass the privateKey in JsonWebKey format for a slight performance gain. * You can convert raw keys to JWK using the privateKeyToJWK function. */ - async createSignature(payload: Uint8Array, privateKey: Uint8Array | webcrypto.JsonWebKey): Promise { + async createSignature(payload: Uint8Array, privateKey: Uint8Array | Jwk): Promise { + const subtleCrypto = getSubtle() + const jwk = privateKey instanceof Uint8Array ? this.privateKeyToJWK(privateKey) : privateKey /** @@ -229,8 +232,8 @@ export class EcdsaSecp256r1 extends SigningUtil { return new Uint8Array(signature) } - private async publicKeyToCryptoKey(publicKey: Uint8Array): Promise { - return subtleCrypto.importKey( + private async publicKeyToCryptoKey(publicKey: Uint8Array): Promise { + return getSubtle().importKey( 'raw', publicKey, { @@ -243,7 +246,7 @@ export class EcdsaSecp256r1 extends SigningUtil { } async verifySignature(publicKey: UserIDRaw, payload: Uint8Array, signature: Uint8Array): Promise { - let key: webcrypto.CryptoKey + let key: CryptoKey | undefined try { key = await this.publicKeyToCryptoKey(publicKey) @@ -257,7 +260,7 @@ export class EcdsaSecp256r1 extends SigningUtil { } } - const isValid = await subtleCrypto.verify( + const isValid = await getSubtle().verify( { name: 'ECDSA', hash: { name: 'SHA-256' } @@ -317,13 +320,4 @@ export class MlDsa87 extends SigningUtil { throw new Error(`The given ML-DSA public key and private key don't match!`) } } - -} - -// Declared at the bottom of the file because the classes need to be -// declared first. TS makes sure all KeyPairTypes are present. -const keyTypeToInstance: Record = { - ECDSA_SECP256K1_EVM: new EcdsaSecp256k1Evm(), - ECDSA_SECP256R1: new EcdsaSecp256r1(), - ML_DSA_87: new MlDsa87() } diff --git a/packages/utils/src/binaryUtils.ts b/packages/utils/src/binaryUtils.ts index 288aa0fbba..e9d3bc05ae 100644 --- a/packages/utils/src/binaryUtils.ts +++ b/packages/utils/src/binaryUtils.ts @@ -1,12 +1,9 @@ -const textEncoder = new TextEncoder() -const textDecoder = new TextDecoder() - export const binaryToUtf8 = (bytes: Uint8Array): string => { - return textDecoder.decode(bytes) + return new TextDecoder().decode(bytes) } export const utf8ToBinary = (utf8: string): Uint8Array => { - return textEncoder.encode(utf8) + return new TextEncoder().encode(utf8) } export const binaryToHex = (bytes: Uint8Array, addPrefix = false): string => { diff --git a/packages/utils/src/browser/crypto.ts b/packages/utils/src/browser/crypto.ts new file mode 100644 index 0000000000..de13cf1715 --- /dev/null +++ b/packages/utils/src/browser/crypto.ts @@ -0,0 +1,63 @@ +import md5 from 'md5' +import { + createCipheriv as createCipherivUtil, + createDecipheriv as createDecipherivUtil, +} from 'browserify-aes' +import aesModes from 'browserify-aes/modes' +import { sha1 } from '@noble/hashes/legacy.js' +import type { Transform } from 'readable-stream' +import { utf8ToBinary } from '../binaryUtils' + +export function getSubtle(): SubtleCrypto { + const { crypto } = globalThis + + if (!crypto?.subtle) { + const url = + 'https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto' + throw new Error( + `SubtleCrypto not supported. This feature is available only in secure contexts (HTTPS). ${url}` + ) + } + + return crypto.subtle +} + +export function computeMd5(input: string): Buffer { + return Buffer.from(md5(input), 'hex') +} + +export function computeSha1(input: string): Buffer { + return Buffer.from(sha1(utf8ToBinary(input))) +} + +export type Jwk = JsonWebKey + +export type CryptoKey = globalThis.CryptoKey + +export function createCipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null +): Transform { + const suite = algorithm.toLowerCase() + + if (aesModes[suite]) { + return createCipherivUtil(suite, key, iv) + } + + throw new TypeError(`Invalid suite type. In browser only AES is supported but got ${algorithm}.`) +} + +export function createDecipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null +): Transform { + const suite = algorithm.toLowerCase() + + if (aesModes[suite]) { + return createDecipherivUtil(suite, key, iv) + } + + throw new TypeError(`Invalid suite type. In browser only AES is supported but got ${algorithm}.`) +} diff --git a/packages/utils/src/browser/env.ts b/packages/utils/src/browser/env.ts new file mode 100644 index 0000000000..bd33e9013f --- /dev/null +++ b/packages/utils/src/browser/env.ts @@ -0,0 +1,19 @@ +/** + * Browser-safe environment object. + * + * `process.env` is NOT available in browsers unless explicitly polyfilled + * by the bundler or runtime. This guard prevents runtime errors and falls + * back to an empty object when no polyfill exists. + */ +const defaultEnv: Record = + typeof process !== 'undefined' && process?.env ? process.env : {} + +/** + * Application environment values. + * + * Values here are browser-safe defaults and override any polyfilled + * `process.env` values if present. + */ +export const env = Object.assign(defaultEnv, { + DISABLE_PRETTY_LOG: 'true', +}) diff --git a/packages/utils/src/browser/os.ts b/packages/utils/src/browser/os.ts new file mode 100644 index 0000000000..bb4d2b93e8 --- /dev/null +++ b/packages/utils/src/browser/os.ts @@ -0,0 +1,5 @@ +const os = { + homedir: (): string => '/' +} + +export default os diff --git a/packages/utils/src/browserify-aes.d.ts b/packages/utils/src/browserify-aes.d.ts new file mode 100644 index 0000000000..47f6e60108 --- /dev/null +++ b/packages/utils/src/browserify-aes.d.ts @@ -0,0 +1,44 @@ +declare module 'browserify-aes' { + import type { Transform } from 'readable-stream' + + export interface CipherOptions { + iv?: Buffer | Uint8Array | null + authTagLength?: number + } + + export interface DecipherOptions { + iv?: Buffer | Uint8Array | null + authTagLength?: number + } + + export function createCipher( + algorithm: string, + password: string | Buffer + ): Transform + + export function createCipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null, + options?: CipherOptions + ): Transform + + export function createDecipher( + algorithm: string, + password: string | Buffer + ): Transform + + export function createDecipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null, + options?: DecipherOptions + ): Transform + + export function getCiphers(): string[] +} + +declare module 'browserify-aes/modes' { + const modes: Record + export default modes +} diff --git a/packages/utils/src/crossPlatformCrypto.ts b/packages/utils/src/crossPlatformCrypto.ts deleted file mode 100644 index fa04d35144..0000000000 --- a/packages/utils/src/crossPlatformCrypto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import crypto from 'crypto' - -declare const self: any - -export function getSubtle(): crypto.webcrypto.SubtleCrypto { - // in browser main thread, self === window - // in web workers, self is defined but window is not - // in node.js, self is undefined - const subtle = typeof self !== 'undefined' ? self?.crypto?.subtle : crypto.webcrypto.subtle - if (!subtle) { - const url = 'https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto' - throw new Error(`SubtleCrypto not supported. This feature is available only in secure contexts (HTTPS) & Node 16+. ${url}`) - } - return subtle -} diff --git a/packages/utils/src/executeSafePromise.ts b/packages/utils/src/executeSafePromise.ts index 9b79cc19fb..a464e9b461 100644 --- a/packages/utils/src/executeSafePromise.ts +++ b/packages/utils/src/executeSafePromise.ts @@ -1,7 +1,5 @@ import { Logger } from './Logger' -const logger = new Logger('executeSafePromise') - /** * Execute a promise that should never reject. If it does, log the error and exit the process * (in Node/Electron) or throw an unhandled error (in browsers). @@ -9,9 +7,11 @@ const logger = new Logger('executeSafePromise') * to reject (unless something is really wrong). */ export const executeSafePromise = async (createPromise: () => Promise): Promise => { + try { return await createPromise() } catch (err: any) { + const logger = new Logger('executeSafePromise') logger.fatal('Assertion failure!', { message: err?.message, err }) // Check if we're in a Node/Electron environment diff --git a/packages/utils/src/exports-browser.ts b/packages/utils/src/exports-browser.ts new file mode 100644 index 0000000000..a0a5ae2ca5 --- /dev/null +++ b/packages/utils/src/exports-browser.ts @@ -0,0 +1,6 @@ +/** + * `buffer-shim` polyfills `globalThis.Buffer` in browsers via `buffer` package. + */ +import 'buffer-shim' + +export * from './exports' diff --git a/packages/utils/src/exports.ts b/packages/utils/src/exports.ts index c485f4b9bf..519581734d 100644 --- a/packages/utils/src/exports.ts +++ b/packages/utils/src/exports.ts @@ -53,5 +53,6 @@ export { type UserID, type UserIDRaw, toUserId, toUserIdRaw, isValidUserId, isEt export type { HexString } from './HexString' export type { ChangeFieldType, MapKey } from './types' export { type WeiAmount, multiplyWeiAmount } from './WeiAmount' -export { getSubtle } from './crossPlatformCrypto' +export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv } from '@/crypto' export { SigningUtil, EcdsaSecp256k1Evm, EcdsaSecp256r1, MlDsa87, type KeyType, KEY_TYPES } from './SigningUtil' +export { randomBytes } from '@noble/post-quantum/utils' diff --git a/packages/utils/src/keyToArrayIndex.ts b/packages/utils/src/keyToArrayIndex.ts index c248b02fb8..0fa87dde28 100644 --- a/packages/utils/src/keyToArrayIndex.ts +++ b/packages/utils/src/keyToArrayIndex.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto' +import { computeMd5 } from '@/crypto' /** * Computes a deterministic index for a given string or number key. @@ -25,7 +25,6 @@ export function keyToArrayIndex(lengthOfArray: number, key: string | number): nu } // String key handling - const buffer = crypto.createHash('md5').update(key).digest() - const intHash = buffer.readInt32LE(0) + const intHash = computeMd5(key).readInt32LE(0) return Math.abs(intHash) % lengthOfArray } diff --git a/packages/utils/src/nodejs/crypto.ts b/packages/utils/src/nodejs/crypto.ts new file mode 100644 index 0000000000..cfeb7c8573 --- /dev/null +++ b/packages/utils/src/nodejs/crypto.ts @@ -0,0 +1,43 @@ +import crypto, { type webcrypto } from 'crypto' + +export function getSubtle(): crypto.webcrypto.SubtleCrypto { + const subtle = crypto.webcrypto.subtle + + if (!subtle) { + const url = + 'https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto' + throw new Error( + `SubtleCrypto not supported. This feature is available only in Node 16+. ${url}` + ) + } + + return subtle +} + +export type Jwk = webcrypto.JsonWebKey + +export type CryptoKey = webcrypto.CryptoKey + +export function computeMd5(input: string): Buffer { + return crypto.createHash('md5').update(input).digest() +} + +export function computeSha1(input: string): Buffer { + return crypto.createHash('sha1').update(input).digest() +} + +export function createCipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null +): crypto.Cipheriv { + return crypto.createCipheriv(algorithm, key, iv) +} + +export function createDecipheriv( + algorithm: string, + key: Buffer | Uint8Array, + iv: Buffer | Uint8Array | null +): crypto.Decipheriv { + return crypto.createDecipheriv(algorithm, key, iv) +} diff --git a/packages/utils/src/nodejs/env.ts b/packages/utils/src/nodejs/env.ts new file mode 100644 index 0000000000..7c9e55cfbb --- /dev/null +++ b/packages/utils/src/nodejs/env.ts @@ -0,0 +1,6 @@ +/** + * Node.js environment object. + * + * Directly exposes `process.env`. + */ +export const env: Record = process.env diff --git a/packages/utils/test/Metric.test.ts b/packages/utils/test/Metric.test.ts index b34acab019..d0f10a4345 100644 --- a/packages/utils/test/Metric.test.ts +++ b/packages/utils/test/Metric.test.ts @@ -1,5 +1,5 @@ import { wait } from '../src/wait' -import { AverageMetric, CountMetric, LevelMetric, MetricsContext, MetricsReport, RateMetric } from '../src/Metric' +import { AverageMetric, CountMetric, LevelMetric, MetricsContext, type MetricsReport, RateMetric } from '../src/Metric' import { until } from '../src/until' const REPORT_INTERVAL = 100 diff --git a/packages/utils/test/composeAbortSignals.test.ts b/packages/utils/test/composeAbortSignals.test.ts index 417e313ec8..60e8269f55 100644 --- a/packages/utils/test/composeAbortSignals.test.ts +++ b/packages/utils/test/composeAbortSignals.test.ts @@ -1,4 +1,4 @@ -import { ComposedAbortSignal, composeAbortSignals } from '../src/composeAbortSignals' +import { type ComposedAbortSignal, composeAbortSignals } from '../src/composeAbortSignals' import range from 'lodash/range' describe('composeAbortSignals', () => { diff --git a/packages/utils/tsconfig.browser.json b/packages/utils/tsconfig.browser.json new file mode 100644 index 0000000000..abb91eabd0 --- /dev/null +++ b/packages/utils/tsconfig.browser.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.browser.json", + "compilerOptions": { + "outDir": "dist/browser", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/browser/*" + ] + } + }, + "include": [ + "src" + ], + "exclude": [ + "src/nodejs" + ] +} diff --git a/packages/utils/tsconfig.jest.json b/packages/utils/tsconfig.jest.json index a826798cda..7746d1c6d4 100644 --- a/packages/utils/tsconfig.jest.json +++ b/packages/utils/tsconfig.jest.json @@ -1,7 +1,25 @@ { "extends": "../../tsconfig.jest.json", + "compilerOptions": { + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/nodejs/*" + ] + } + }, "include": [ "src", "test" + ], + "exclude": [ + "src/browser" + ], + "references": [ + { "path": "./tsconfig.browser.json" } ] } diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 126cae2a06..9a557a2379 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -1,9 +1,10 @@ { - "extends": "../../tsconfig.node.json", + "files": [], "compilerOptions": { - "outDir": "dist" + "composite": true }, - "include": [ - "src" + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.browser.json" } ] } diff --git a/packages/utils/tsconfig.karma.json b/packages/utils/tsconfig.karma.json index 14f74739f8..662d21a06b 100644 --- a/packages/utils/tsconfig.karma.json +++ b/packages/utils/tsconfig.karma.json @@ -5,7 +5,15 @@ "jest", "jest-extended" ], - "outDir": "dist" + "outDir": "dist/karma", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/browser/*" + ] + } }, "include": [ "src" diff --git a/packages/utils/tsconfig.node.json b/packages/utils/tsconfig.node.json new file mode 100644 index 0000000000..a5a0284500 --- /dev/null +++ b/packages/utils/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "outDir": "dist/nodejs", + + /* Resolution */ + "moduleResolution": "bundler", + "module": "preserve", + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/nodejs/*" + ] + } + }, + "include": [ + "src" + ], + "exclude": [ + "src/browser" + ] +} diff --git a/tsconfig.browser.json b/tsconfig.browser.json new file mode 100644 index 0000000000..4094e8dc8b --- /dev/null +++ b/tsconfig.browser.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM"], + "module": "ESNext", + "types": [], + "skipLibCheck": true, + "declaration": true, + "composite": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "noImplicitOverride": true, + "noImplicitAny": true + }, + "include": [], + "exclude": [] +} diff --git a/tsconfig.jest.json b/tsconfig.jest.json index 819ffe9c34..a000f066f1 100644 --- a/tsconfig.jest.json +++ b/tsconfig.jest.json @@ -10,7 +10,7 @@ "node", "jest", "jest-extended", - "@streamr/test-utils/customMatcherTypes" + "@streamr/test-utils/customMatchers" ], "sourceMap": false } diff --git a/tsconfig.karma.json b/tsconfig.karma.json index 599e6fba27..6558ff9a48 100644 --- a/tsconfig.karma.json +++ b/tsconfig.karma.json @@ -18,7 +18,7 @@ "types": [ "jest", "jest-extended", - "@streamr/test-utils/customMatcherTypes" + "@streamr/test-utils/customMatchers" ], "sourceMap": true, "skipLibCheck": true,