diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index df4032962..3b46ba29f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,55 +1,8 @@ name: Bug Report description: File a bug report -title: "" +#title: "" labels: ["Bug", "Pending Triage"] body: - - type: input - id: bom-cli-version - attributes: - label: Bill of Materials or CLI Version - description: Which version of the BOM or CLI are you using? - placeholder: | - ex. 0.18.2 or git commit ID - - The bill of materials version can be found in your Gradle or Maven - build configuration. The CLI version can be found by using the `--version` switch. - - type: dropdown - id: execution-environment - attributes: - label: Execution Environment - description: Which front-end execution environment are you using? - options: - - JUnit Extensions - - Performance CLI - - Local Node CLI - - Other - validations: - required: true - - type: dropdown - id: logging-implementation - attributes: - label: Slf4j Logging Implementation - description: Which slf4j compatible logging implementation are you using? **JUnit Users Only** - options: - - Log4j 1.x - - Log4j 2.x - - Logback Classic - - Other - validations: - required: false - - type: textarea - id: reproduction-steps - attributes: - label: To Reproduce - description: Steps to reproduce the behavior - render: markdown - placeholder: | - 1. Go to '...' - 2. Click on '....' - 3. Scroll down to '....' - 4. See error - validations: - required: true - type: textarea id: actual-behavior attributes: @@ -67,13 +20,15 @@ body: validations: required: true - type: textarea - id: test-cli-logs + id: reproduction-steps attributes: - label: Whole JUnit/CLI Logs - description: "NEVER EVER OMIT THIS! Include logs from JUnit test output or CLI console/log file output. Don't omit the parts you think irrelevant!" - render: shell + label: To Reproduce + description: Steps to reproduce the behavior placeholder: | - PROVIDE THE LOGS VIA A GIST LINK (https://gist.github.com/), NOT DIRECTLY IN THIS TEXT AREA + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error validations: required: true - type: textarea diff --git a/.github/ISSUE_TEMPLATE/feature_enhancement.yml b/.github/ISSUE_TEMPLATE/feature_enhancement.yml index ac9097d12..7aece8b03 100644 --- a/.github/ISSUE_TEMPLATE/feature_enhancement.yml +++ b/.github/ISSUE_TEMPLATE/feature_enhancement.yml @@ -1,6 +1,6 @@ name: Feature Enhancement description: Enhance an existing feature -title: "" +#title: "" labels: ["Feature Enhancement", "Pending Triage"] body: - type: textarea @@ -18,7 +18,6 @@ body: attributes: label: Requested Enhancement description: What would you like to enhance or change about this feature? - render: markdown placeholder: | _A clear and concise description of what you want to happen._ @@ -30,7 +29,6 @@ body: attributes: label: Business Need description: Why is this needed? - render: markdown placeholder: | _A clear and concise description of any alternative solutions or other features you've considered._ diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 52b111b04..69e08e330 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: New Feature description: Request a new feature -title: "" +#title: "" labels: ["New Feature", "Pending Triage"] body: - type: textarea @@ -8,7 +8,6 @@ body: attributes: label: Requested Feature description: What would you like added? - render: markdown placeholder: | _A clear and concise description of what you want to happen._ @@ -20,7 +19,6 @@ body: attributes: label: Business Need description: Why is this needed? - render: markdown placeholder: | _A clear and concise description of any alternative solutions or features you've considered._ diff --git a/.mocharc.yaml b/.mocharc.yaml index 5afeb2028..64788da21 100644 --- a/.mocharc.yaml +++ b/.mocharc.yaml @@ -23,8 +23,12 @@ verbose: true file: - test/setup.ts require: - - ts-node/register - test/setup.ts extension: - ts -loader: ts-node/esm +node-option: + - 'enable-source-maps' + - 'import=tsx' +full-trace: true +enable-source-maps: true +ui: bdd diff --git a/.swcrc b/.swcrc deleted file mode 100644 index e63add844..000000000 --- a/.swcrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://swc.rs/schema.json", - "jsc": { - "parser": { - "syntax": "typescript", - "tsx": false, - "decorators": false, - "dynamicImport": true - }, - "target": "es2022", - "baseUrl": "..", - "preserveAllComments": true - }, - "module": { - "type": "es6" - }, - "minify": false -} \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index e0c21dda2..5f3cff146 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -68,7 +68,7 @@ export default [ "@typescript-eslint/consistent-type-imports": ["error", { fixStyle: 'inline-type-imports'}], 'space-before-function-paren': 'error', '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/class-literal-property-style': 'off' + '@typescript-eslint/class-literal-property-style': 'off', } }, { diff --git a/package-lock.json b/package-lock.json index 6757a6d3d..1d92f4ef6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "semver": "^7.6.3", "stream-buffers": "^3.0.3", "tar": "^7.4.3", - "ts-node": "^10.9.2", + "tsx": "^4.19.2", "uuid": "^11.0.3", "winston": "^3.17.0", "yaml": "^2.6.1", @@ -47,8 +47,6 @@ }, "devDependencies": { "@eslint/js": "^9.15.0", - "@swc/cli": "^0.5.1", - "@swc/core": "^1.9.2", "@types/adm-zip": "^0.5.6", "@types/chai": "^5.0.1", "@types/chai-as-promised": "^8.0.1", @@ -237,28 +235,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", @@ -269,6 +245,366 @@ "kuler": "^2.0.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -1331,6 +1667,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -1338,7 +1675,8 @@ "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==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -1414,351 +1752,46 @@ "enquirer": ">= 2.3.0 < 3" } }, - "node_modules/@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true - }, - "node_modules/@microsoft/tsdoc-config": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", - "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.15.0", - "ajv": "~8.12.0", - "jju": "~1.4.0", - "resolve": "~1.22.2" - } - }, - "node_modules/@microsoft/tsdoc-config/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/@napi-rs/nice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", - "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/nice-android-arm-eabi": "1.0.1", - "@napi-rs/nice-android-arm64": "1.0.1", - "@napi-rs/nice-darwin-arm64": "1.0.1", - "@napi-rs/nice-darwin-x64": "1.0.1", - "@napi-rs/nice-freebsd-x64": "1.0.1", - "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", - "@napi-rs/nice-linux-arm64-gnu": "1.0.1", - "@napi-rs/nice-linux-arm64-musl": "1.0.1", - "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", - "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", - "@napi-rs/nice-linux-s390x-gnu": "1.0.1", - "@napi-rs/nice-linux-x64-gnu": "1.0.1", - "@napi-rs/nice-linux-x64-musl": "1.0.1", - "@napi-rs/nice-win32-arm64-msvc": "1.0.1", - "@napi-rs/nice-win32-ia32-msvc": "1.0.1", - "@napi-rs/nice-win32-x64-msvc": "1.0.1" - } - }, - "node_modules/@napi-rs/nice-android-arm-eabi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", - "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-android-arm64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", - "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-darwin-arm64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", - "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-darwin-x64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", - "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-freebsd-x64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", - "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", - "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", - "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm64-musl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", - "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-ppc64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", - "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-riscv64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", - "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-s390x-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", - "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-x64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", - "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-x64-musl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", - "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-win32-arm64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", - "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-win32-ia32-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", - "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", - "cpu": [ - "ia32" - ], + "node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", + "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "@microsoft/tsdoc": "0.15.0", + "ajv": "~8.12.0", + "jju": "~1.4.0", + "resolve": "~1.22.2" } }, - "node_modules/@napi-rs/nice-win32-x64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", - "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", - "cpu": [ - "x64" - ], + "node_modules/@microsoft/tsdoc-config/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2135,368 +2168,84 @@ "version": "1.22.0", "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.0.tgz", "integrity": "sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==", - "dev": true, - "dependencies": { - "@shikijs/vscode-textmate": "^9.3.0", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", - "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", - "dev": true - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.1.tgz", - "integrity": "sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", - "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", - "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1", - "lodash.get": "^4.4.2", - "type-detect": "^4.1.0" - } - }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", - "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", - "dev": true, - "license": "(Unlicense OR Apache-2.0)" - }, - "node_modules/@swc/cli": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.5.1.tgz", - "integrity": "sha512-sxSXyjqFImYrqjhZSPymjmM/9V6auZG67UsDwbe7FZaBlyfW8ka3QG/zRjpJJ9+8Ahns/kKb8bXPKQq7V2MtBw==", - "dev": true, - "dependencies": { - "@swc/counter": "^0.1.3", - "@xhmikosr/bin-wrapper": "^13.0.5", - "commander": "^8.3.0", - "fast-glob": "^3.2.5", - "minimatch": "^9.0.3", - "piscina": "^4.3.0", - "semver": "^7.3.8", - "slash": "3.0.0", - "source-map": "^0.7.3" - }, - "bin": { - "spack": "bin/spack.js", - "swc": "bin/swc.js", - "swcx": "bin/swcx.js" - }, - "engines": { - "node": ">= 16.14.0" - }, - "peerDependencies": { - "@swc/core": "^1.2.66", - "chokidar": "^3.5.1" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@swc/cli/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@swc/cli/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/@swc/cli/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@swc/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.9.2.tgz", - "integrity": "sha512-dYyEkO6mRYtZFpnOsnYzv9rY69fHAHoawYOjGOEcxk9WYtaJhowMdP/w6NcOKnz2G7GlZaenjkzkMa6ZeQeMsg==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.15" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.9.2", - "@swc/core-darwin-x64": "1.9.2", - "@swc/core-linux-arm-gnueabihf": "1.9.2", - "@swc/core-linux-arm64-gnu": "1.9.2", - "@swc/core-linux-arm64-musl": "1.9.2", - "@swc/core-linux-x64-gnu": "1.9.2", - "@swc/core-linux-x64-musl": "1.9.2", - "@swc/core-win32-arm64-msvc": "1.9.2", - "@swc/core-win32-ia32-msvc": "1.9.2", - "@swc/core-win32-x64-msvc": "1.9.2" - }, - "peerDependencies": { - "@swc/helpers": "*" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.2.tgz", - "integrity": "sha512-nETmsCoY29krTF2PtspEgicb3tqw7Ci5sInTI03EU5zpqYbPjoPH99BVTjj0OsF53jP5MxwnLI5Hm21lUn1d6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.9.2.tgz", - "integrity": "sha512-9gD+bwBz8ZByjP6nZTXe/hzd0tySIAjpDHgkFiUrc+5zGF+rdTwhcNrzxNHJmy6mw+PW38jqII4uspFHUqqxuQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.2.tgz", - "integrity": "sha512-kYq8ief1Qrn+WmsTWAYo4r+Coul4dXN6cLFjiPZ29Cv5pyU+GFvSPAB4bEdMzwy99rCR0u2P10UExaeCjurjvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.2.tgz", - "integrity": "sha512-n0W4XiXlmEIVqxt+rD3ZpkogsEWUk1jJ+i5bQNgB+1JuWh0fBE8c/blDgTQXa0GB5lTPVDZQussgdNOCnAZwiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.2.tgz", - "integrity": "sha512-8xzrOmsyCC1zrx2Wzx/h8dVsdewO1oMCwBTLc1gSJ/YllZYTb04pNm6NsVbzUX2tKddJVRgSJXV10j/NECLwpA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" } }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.2.tgz", - "integrity": "sha512-kZrNz/PjRQKcchWF6W292jk3K44EoVu1ad5w+zbS4jekIAxsM8WwQ1kd+yjUlN9jFcF8XBat5NKIs9WphJCVXg==", - "cpu": [ - "x64" - ], + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", + "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.1.tgz", + "integrity": "sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==", "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.2.tgz", - "integrity": "sha512-TTIpR4rjMkhX1lnFR+PSXpaL83TrQzp9znRdp2TzYrODlUd/R20zOwSo9vFLCyH6ZoD47bccY7QeGZDYT3nlRg==", - "cpu": [ - "x64" - ], + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" } }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.2.tgz", - "integrity": "sha512-+Eg2d4icItKC0PMjZxH7cSYFLWk0aIp94LNmOw6tPq0e69ax6oh10upeq0D1fjWsKLmOJAWEvnXlayZcijEXDw==", - "cpu": [ - "arm64" - ], + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" } }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.2.tgz", - "integrity": "sha512-nLWBi4vZDdM/LkiQmPCakof8Dh1/t5EM7eudue04V1lIcqx9YHVRS3KMwEaCoHLGg0c312Wm4YgrWQd9vwZ5zQ==", - "cpu": [ - "ia32" - ], + "node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" } }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.2.tgz", - "integrity": "sha512-ik/k+JjRJBFkXARukdU82tSVx0CbExFQoQ78qTO682esbYXzjdB5eLVkoUbwen299pnfr88Kn4kyIqFPTje8Xw==", - "cpu": [ - "x64" - ], + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "devOptional": true, - "license": "Apache-2.0" - }, - "node_modules/@swc/types": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.15.tgz", - "integrity": "sha512-XKaZ+dzDIQ9Ot9o89oJQ/aluI17+VvUnIpYJTcZtvv1iYX6MzHh3Ik2CSR7MdPKpPwfZXHBeCingb2b4PoDVdw==", - "devOptional": true, - "dependencies": { - "@swc/counter": "^0.1.3" - } + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", @@ -2509,36 +2258,6 @@ "node": ">=14.16" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "license": "MIT" - }, "node_modules/@types/adm-zip": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.6.tgz", @@ -3136,271 +2855,50 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", - "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.15.0", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@xhmikosr/archive-type": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@xhmikosr/archive-type/-/archive-type-7.0.0.tgz", - "integrity": "sha512-sIm84ZneCOJuiy3PpWR5bxkx3HaNt1pqaN+vncUBZIlPZCq8ASZH+hBVdu5H8znR7qYC6sKwx+ie2Q7qztJTxA==", - "dev": true, - "dependencies": { - "file-type": "^19.0.0" - }, - "engines": { - "node": "^14.14.0 || >=16.0.0" - } - }, - "node_modules/@xhmikosr/bin-check": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@xhmikosr/bin-check/-/bin-check-7.0.3.tgz", - "integrity": "sha512-4UnCLCs8DB+itHJVkqFp9Zjg+w/205/J2j2wNBsCEAm/BuBmtua2hhUOdAMQE47b1c7P9Xmddj0p+X1XVsfHsA==", - "dev": true, - "dependencies": { - "execa": "^5.1.1", - "isexe": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/bin-wrapper": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@xhmikosr/bin-wrapper/-/bin-wrapper-13.0.5.tgz", - "integrity": "sha512-DT2SAuHDeOw0G5bs7wZbQTbf4hd8pJ14tO0i4cWhRkIJfgRdKmMfkDilpaJ8uZyPA0NVRwasCNAmMJcWA67osw==", - "dev": true, - "dependencies": { - "@xhmikosr/bin-check": "^7.0.3", - "@xhmikosr/downloader": "^15.0.1", - "@xhmikosr/os-filter-obj": "^3.0.0", - "bin-version-check": "^5.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/decompress": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@xhmikosr/decompress/-/decompress-10.0.1.tgz", - "integrity": "sha512-6uHnEEt5jv9ro0CDzqWlFgPycdE+H+kbJnwyxgZregIMLQ7unQSCNVsYG255FoqU8cP46DyggI7F7LohzEl8Ag==", - "dev": true, - "dependencies": { - "@xhmikosr/decompress-tar": "^8.0.1", - "@xhmikosr/decompress-tarbz2": "^8.0.1", - "@xhmikosr/decompress-targz": "^8.0.1", - "@xhmikosr/decompress-unzip": "^7.0.0", - "graceful-fs": "^4.2.11", - "make-dir": "^4.0.0", - "strip-dirs": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/decompress-tar": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-tar/-/decompress-tar-8.0.1.tgz", - "integrity": "sha512-dpEgs0cQKJ2xpIaGSO0hrzz3Kt8TQHYdizHsgDtLorWajuHJqxzot9Hbi0huRxJuAGG2qiHSQkwyvHHQtlE+fg==", - "dev": true, - "dependencies": { - "file-type": "^19.0.0", - "is-stream": "^2.0.1", - "tar-stream": "^3.1.7" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/decompress-tarbz2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-tarbz2/-/decompress-tarbz2-8.0.1.tgz", - "integrity": "sha512-OF+6DysDZP5YTDO8uHuGG6fMGZjc+HszFPBkVltjoje2Cf60hjBg/YP5OQndW1hfwVWOdP7f3CnJiPZHJUTtEg==", - "dev": true, - "dependencies": { - "@xhmikosr/decompress-tar": "^8.0.1", - "file-type": "^19.0.0", - "is-stream": "^2.0.1", - "seek-bzip": "^2.0.0", - "unbzip2-stream": "^1.4.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/decompress-targz": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-targz/-/decompress-targz-8.0.1.tgz", - "integrity": "sha512-mvy5AIDIZjQ2IagMI/wvauEiSNHhu/g65qpdM4EVoYHUJBAmkQWqcPJa8Xzi1aKVTmOA5xLJeDk7dqSjlHq8Mg==", - "dev": true, - "dependencies": { - "@xhmikosr/decompress-tar": "^8.0.1", - "file-type": "^19.0.0", - "is-stream": "^2.0.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/decompress-unzip": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-unzip/-/decompress-unzip-7.0.0.tgz", - "integrity": "sha512-GQMpzIpWTsNr6UZbISawsGI0hJ4KA/mz5nFq+cEoPs12UybAqZWKbyIaZZyLbJebKl5FkLpsGBkrplJdjvUoSQ==", - "dev": true, - "dependencies": { - "file-type": "^19.0.0", - "get-stream": "^6.0.1", - "yauzl": "^3.1.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/downloader": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@xhmikosr/downloader/-/downloader-15.0.1.tgz", - "integrity": "sha512-fiuFHf3Dt6pkX8HQrVBsK0uXtkgkVlhrZEh8b7VgoDqFf+zrgFBPyrwCqE/3nDwn3hLeNz+BsrS7q3mu13Lp1g==", - "dev": true, - "dependencies": { - "@xhmikosr/archive-type": "^7.0.0", - "@xhmikosr/decompress": "^10.0.1", - "content-disposition": "^0.5.4", - "defaults": "^3.0.0", - "ext-name": "^5.0.0", - "file-type": "^19.0.0", - "filenamify": "^6.0.0", - "get-stream": "^6.0.1", - "got": "^13.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@xhmikosr/downloader/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@xhmikosr/downloader/node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@xhmikosr/downloader/node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "dev": true, - "engines": { - "node": ">= 14.17" + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@xhmikosr/downloader/node_modules/got": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz", - "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", + "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", "dev": true, "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" + "@typescript-eslint/types": "8.15.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": ">=16" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@xhmikosr/downloader/node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "engines": { - "node": ">=12.20" - } - }, - "node_modules/@xhmikosr/os-filter-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@xhmikosr/os-filter-obj/-/os-filter-obj-3.0.0.tgz", - "integrity": "sha512-siPY6BD5dQ2SZPl3I0OZBHL27ZqZvLEosObsZRQ1NUB8qcxegwt0T9eKtV96JMFQpIz1elhkzqOg4c/Ri6Dp9A==", - "dev": true, - "dependencies": { - "arch": "^3.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": "^14.14.0 || >=16.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -3440,18 +2938,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adm-zip": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", @@ -3532,32 +3018,6 @@ "node": ">= 8" } }, - "node_modules/arch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-3.0.0.tgz", - "integrity": "sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3773,12 +3233,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "dev": true - }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -3794,13 +3248,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", - "dev": true, - "optional": true - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3841,39 +3288,6 @@ "node": "*" } }, - "node_modules/bin-version": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz", - "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "find-versions": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bin-version-check": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz", - "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==", - "dev": true, - "dependencies": { - "bin-version": "^6.0.0", - "semver": "^7.5.3", - "semver-truncate": "^3.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3949,15 +3363,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4509,18 +3914,6 @@ "typedarray": "^0.0.6" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4532,12 +3925,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "license": "MIT" - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -4725,18 +4112,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/defaults": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-3.0.0.tgz", - "integrity": "sha512-RsqXDEAALjfRTro+IFNKpcPCt0/Cy2FqHSIlnomiJp9YGadpQnrtbRpSgN2+np21qHcIKiva4fiOQGjS9/qR/A==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", @@ -5102,6 +4477,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -5649,54 +5062,6 @@ "node": ">=0.8.x" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "dependencies": { - "mime-db": "^1.28.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "dependencies": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -5733,12 +5098,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -5845,79 +5204,6 @@ "node": ">=16.0.0" } }, - "node_modules/file-type": { - "version": "19.6.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz", - "integrity": "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==", - "dev": true, - "dependencies": { - "get-stream": "^9.0.1", - "strtok3": "^9.0.1", - "token-types": "^6.0.0", - "uint8array-extras": "^1.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, - "node_modules/file-type/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-type/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/filename-reserved-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", - "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/filenamify": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", - "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", - "dev": true, - "dependencies": { - "filename-reserved-regex": "^3.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -5946,21 +5232,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-versions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", - "dev": true, - "dependencies": { - "semver-regex": "^4.0.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -6096,7 +5367,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -6190,18 +5460,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -6223,7 +5481,6 @@ "version": "4.8.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", - "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -6576,15 +5833,6 @@ "node": ">=10.19.0" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6708,15 +5956,6 @@ "@types/node": ">=18" } }, - "node_modules/inspect-with-kind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/inspect-with-kind/-/inspect-with-kind-1.0.5.tgz", - "integrity": "sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - } - }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -7426,18 +6665,9 @@ "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" } }, "node_modules/klaw": { @@ -7856,12 +7086,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "license": "ISC" - }, "node_modules/markdown-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", @@ -8114,12 +7338,6 @@ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8621,15 +7839,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -9083,18 +8292,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -9225,21 +8422,6 @@ "fn.name": "1.x.x" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/oniguruma-to-js": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", @@ -9446,25 +8628,6 @@ "node": ">= 14.16" } }, - "node_modules/peek-readable": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz", - "integrity": "sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -9577,16 +8740,6 @@ "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" }, - "node_modules/piscina": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", - "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "@napi-rs/nice": "^1.0.1" - } - }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -9754,12 +8907,6 @@ ], "license": "MIT" }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -10612,7 +9759,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -10804,19 +9950,6 @@ "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" }, - "node_modules/seek-bzip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-2.0.0.tgz", - "integrity": "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==", - "dev": true, - "dependencies": { - "commander": "^6.0.0" - }, - "bin": { - "seek-bunzip": "bin/seek-bunzip", - "seek-table": "bin/seek-bzip-table" - } - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -10828,33 +9961,6 @@ "node": ">=10" } }, - "node_modules/semver-regex": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", - "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver-truncate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz", - "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -10948,12 +10054,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -11002,16 +10102,6 @@ "node": ">=0.3.1" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/slice-ansi": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", @@ -11057,49 +10147,6 @@ "atomic-sleep": "^1.0.0" } }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", - "dev": true, - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", - "dev": true, - "dependencies": { - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -11174,20 +10221,6 @@ "node": ">= 0.10.0" } }, - "node_modules/streamx": { - "version": "2.20.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz", - "integrity": "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -11309,34 +10342,6 @@ "node": ">=8" } }, - "node_modules/strip-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-3.0.0.tgz", - "integrity": "sha512-I0sdgcFTfKQlUPZyAqPJmSG3HLO9rWDFnxonnIbskYNM3DwFOeTNB5KzVq3dA1GdRAc/25b5Y7UO2TQfKWw4aQ==", - "dev": true, - "dependencies": { - "inspect-with-kind": "^1.0.5", - "is-plain-obj": "^1.1.0" - } - }, - "node_modules/strip-dirs/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11348,23 +10353,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strtok3": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.0.1.tgz", - "integrity": "sha512-ERPW+XkvX9W2A+ov07iy+ZFJpVdik04GhDA4eVogiG9hpC97Kem2iucyzhFxbFRvQ5o2UckFtKZdp1hkGvnrEw==", - "dev": true, - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.3.1" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11415,17 +10403,6 @@ "node": ">=18" } }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/tar/node_modules/mkdirp": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", @@ -11521,12 +10498,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", - "dev": true - }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -11546,12 +10517,6 @@ "real-require": "^0.2.0" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11575,23 +10540,6 @@ "node": ">=8.0" } }, - "node_modules/token-types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz", - "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==", - "dev": true, - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -11645,58 +10593,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -11738,6 +10634,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" }, + "node_modules/tsx": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", + "dependencies": { + "esbuild": "~0.23.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.8.0", "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.8.0.tgz", @@ -11932,6 +10846,7 @@ "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -11972,18 +10887,6 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, - "node_modules/uint8array-extras": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", - "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11999,40 +10902,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "node_modules/unbzip2-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/underscore": { "version": "1.13.7", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", @@ -12396,12 +11265,6 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "license": "MIT" - }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -12841,28 +11704,6 @@ "node": ">=8" } }, - "node_modules/yauzl": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", - "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "pend": "~1.2.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index dc54cb98d..9fd71e21c 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test": "cross-env MOCHA_SUITE_NAME=\"Unit Tests\" c8 --report-dir='coverage/unit' mocha 'test/unit/**/*.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit.xml", "test-e2e-all": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E All Tests\" c8 --report-dir='coverage/e2e-all' mocha 'test/e2e/**/*.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-all.xml", "test-e2e-integration": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Integration Tests\" c8 --report-dir='coverage/e2e-integration' mocha 'test/e2e/integration/**/*.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-integration.xml", - "test-e2e-leases": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Lease Tests\" c8 --report-dir='coverage/e2e-leases' mocha 'test/e2e/integration/core/lease_manager.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-integration.xml", + "test-e2e-leases": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Lease Tests\" c8 --report-dir='coverage/e2e-leases' mocha 'test/e2e/integration/core/lease*.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-integration.xml", "test-e2e-standard": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Standard Tests\" c8 --report-dir='coverage/e2e-standard' mocha 'test/e2e/**/*.ts' --ignore 'test/unit/**/*.ts' --ignore 'test/e2e/integration/**/*.ts' --ignore 'test/e2e/commands/mirror_node*.ts' --ignore 'test/e2e/commands/node*.ts' --ignore 'test/e2e/commands/separate_node*.ts' --ignore 'test/e2e/commands/relay*.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-standard.xml --timeout 30000", "test-e2e-mirror-node": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Mirror Node Tests\" c8 --report-dir='coverage/e2e-mirror-node' mocha 'test/e2e/commands/mirror_node.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-mirror-node.xml", "test-e2e-node-pem-stop": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Node PEM Stop Tests\" c8 --report-dir='coverage/e2e-node-pem-stop' mocha 'test/e2e/commands/node_pem_stop.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-node-pem-stop.xml", @@ -30,12 +30,12 @@ "test-e2e-node-delete-separate-commands": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Node Delete - Separate commands Tests\" c8 --report-dir='coverage/e2e-node-delete-separate-commands' mocha 'test/e2e/commands/separate_node_delete*.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-node-delete-separate-commands.xml", "test-e2e-node-upgrade": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Node Upgrade Tests\" c8 --report-dir='coverage/e2e-node-upgrade' mocha 'test/e2e/commands/node_upgrade*.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-node-upgrade.xml", "test-e2e-relay": "cross-env MOCHA_SUITE_NAME=\"Mocha E2E Relay Tests\" c8 --report-dir='coverage/e2e-relay' mocha 'test/e2e/commands/relay.test.ts' --reporter-options configFile=mocha-multi-reporter.json,cmrOutput=mocha-junit-reporter+mochaFile+junit-e2e-relay.xml", - "solo-test": "node --no-deprecation --no-warnings --loader ts-node/esm solo.ts", + "solo-test": "tsx --no-deprecation --no-warnings solo.ts", "solo": "node --no-deprecation --no-warnings dist/solo.js", "check": "remark . --quiet --frail && eslint . --ignore-pattern 'docs/*' --ignore-pattern 'dist/*'; cd docs; jsdoc -c jsdoc.conf.json && tsc", - "format": "remark . --quiet --frail --output && eslint --fix . --ignore-pattern 'docs/*' --ignore-pattern 'dist/*'", + "format": "remark . --quiet --frail --output && eslint --fix . --ignore-pattern 'docs/*' --ignore-pattern 'dist/*' && tsc", "test-setup": "./test/e2e/setup-e2e.sh", - "build": "swc src version.ts solo.ts -d dist && node resources/post-build-script.js" + "build": "tsc && node resources/post-build-script.js" }, "keywords": [ "solo", @@ -67,7 +67,7 @@ "semver": "^7.6.3", "stream-buffers": "^3.0.3", "tar": "^7.4.3", - "ts-node": "^10.9.2", + "tsx": "^4.19.2", "uuid": "^11.0.3", "winston": "^3.17.0", "yaml": "^2.6.1", @@ -75,8 +75,6 @@ }, "devDependencies": { "@eslint/js": "^9.15.0", - "@swc/cli": "^0.5.1", - "@swc/core": "^1.9.2", "@types/adm-zip": "^0.5.6", "@types/chai": "^5.0.1", "@types/chai-as-promised": "^8.0.1", diff --git a/resources/post-build-script.js b/resources/post-build-script.js index 3488e0240..5c7874905 100644 --- a/resources/post-build-script.js +++ b/resources/post-build-script.js @@ -12,31 +12,6 @@ const targetPackageJsonFilePath = path.join(distDir, 'package.json') const srcResourcesDir = path.join(__dirname, '../resources') const targetResourcesDir = path.join(distDir, 'resources') -/** @param {string} filePath */ -function replaceTsWithJs(filePath) { - const fileContent = fs.readFileSync(filePath, 'utf-8') - const updatedContent = fileContent.replace(/(\.ts)(?=['";])/g, '.js') - fs.writeFileSync(filePath, updatedContent) -} - -/** @param {string} dir */ -function traverseDirectory(dir) { - const files = fs.readdirSync(dir) - - for (const file of files) { - const filePath = path.join(dir, file) - const stats = fs.statSync(filePath) - - if (stats.isDirectory()) { - //? Recursively process subdirectories - traverseDirectory(filePath) - } else if (path.extname(file) === '.js') { - //? Process JS files to replace .ts with .js in import paths - replaceTsWithJs(filePath) - } - } -} - function copyPackageJson(srcPackageJsonFilePath, targetPackageJsonFilePath) { fs.copyFileSync(srcPackageJsonFilePath, targetPackageJsonFilePath) } @@ -49,6 +24,3 @@ console.time('Copy package.json') copyPackageJson(srcPackageJsonFilePath, targetPackageJsonFilePath) console.time('Copy resources') copyResources(srcResourcesDir, targetResourcesDir) -console.time('Successfully replaced .ts extensions with .js') -traverseDirectory(distDir) -console.timeEnd('Successfully replaced .ts extensions with .js') diff --git a/solo.ts b/solo.ts index 1938eee8a..d00bd614f 100755 --- a/solo.ts +++ b/solo.ts @@ -15,6 +15,6 @@ * limitations under the License. * */ -import * as fnm from './src/index.ts' +import * as fnm from './src/index.js' fnm.main(process.argv) diff --git a/src/commands/account.ts b/src/commands/account.ts index 9d7116793..0dd04b602 100644 --- a/src/commands/account.ts +++ b/src/commands/account.ts @@ -15,15 +15,17 @@ * */ import chalk from 'chalk' -import { BaseCommand } from './base.ts' -import { SoloError, IllegalArgumentError } from '../core/errors.ts' -import { flags } from './index.ts' +import { BaseCommand } from './base.js' +import { SoloError, IllegalArgumentError } from '../core/errors.js' +import { flags } from './index.js' import { Listr } from 'listr2' -import * as prompts from './prompts.ts' -import { constants, type AccountManager } from '../core/index.ts' +import * as prompts from './prompts.js' +import { constants, type AccountManager } from '../core/index.js' import { type AccountId, AccountInfo, HbarUnit, PrivateKey } from '@hashgraph/sdk' -import { FREEZE_ADMIN_ACCOUNT } from '../core/constants.ts' +import { FREEZE_ADMIN_ACCOUNT } from '../core/constants.js' import { type Opts } from '../types/index.js' +import { ListrLease } from '../core/lease/listr_lease.js' + export class AccountCommand extends BaseCommand { private readonly accountManager: AccountManager private accountInfo: { @@ -249,7 +251,7 @@ export class AccountCommand extends BaseCommand { async create (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: { @@ -294,11 +296,11 @@ export class AccountCommand extends BaseCommand { await self.accountManager.loadNodeClient(ctx.config.namespace) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { - title: 'create the new account.ts', + title: 'create the new account.js', task: async (ctx) => { self.accountInfo = await self.createNewAccount(ctx) const accountInfoCopy = { ...self.accountInfo } diff --git a/src/commands/base.ts b/src/commands/base.ts index 011f8a90b..96e95630d 100644 --- a/src/commands/base.ts +++ b/src/commands/base.ts @@ -16,10 +16,10 @@ */ import paths from 'path' -import { MissingArgumentError } from '../core/errors.ts' -import { ShellRunner } from '../core/shell_runner.ts' -import type { ChartManager, ConfigManager, Helm, K8, DependencyManager, LeaseManager } from '../core/index.ts' -import type { CommandFlag, Opts } from '../types/index.ts' +import { MissingArgumentError } from '../core/errors.js' +import { ShellRunner } from '../core/shell_runner.js' +import type { ChartManager, ConfigManager, Helm, K8, DependencyManager, LeaseManager } from '../core/index.js' +import type { CommandFlag, Opts } from '../types/index.js' export class BaseCommand extends ShellRunner { protected readonly helm: Helm diff --git a/src/commands/cluster.ts b/src/commands/cluster.ts index 524eba370..018ab0f86 100644 --- a/src/commands/cluster.ts +++ b/src/commands/cluster.ts @@ -16,13 +16,14 @@ */ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer' import { Listr } from 'listr2' -import { SoloError } from '../core/errors.ts' -import * as flags from './flags.ts' -import { BaseCommand } from './base.ts' +import { SoloError } from '../core/errors.js' +import * as flags from './flags.js' +import { BaseCommand } from './base.js' import chalk from 'chalk' -import { constants } from '../core/index.ts' -import * as prompts from './prompts.ts' +import { constants } from '../core/index.js' +import * as prompts from './prompts.js' import path from 'path' +import { ListrLease } from '../core/lease/listr_lease.js' /** * Define the core functionalities of 'cluster' command @@ -163,7 +164,7 @@ export class ClusterCommand extends BaseCommand { async reset (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: { @@ -200,7 +201,7 @@ export class ClusterCommand extends BaseCommand { throw new SoloError('No chart found for the cluster') } - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { diff --git a/src/commands/flags.ts b/src/commands/flags.ts index 99ead3899..69795cba8 100644 --- a/src/commands/flags.ts +++ b/src/commands/flags.ts @@ -14,11 +14,11 @@ * limitations under the License. * */ -import { constants } from '../core/index.ts' -import * as core from '../core/index.ts' -import * as version from '../../version.ts' +import { constants } from '../core/index.js' +import * as core from '../core/index.js' +import * as version from '../../version.js' import path from 'path' -import type { CommandFlag } from '../types/index.ts' +import type { CommandFlag } from '../types/index.js' /** * Set flag from the flag option diff --git a/src/commands/index.ts b/src/commands/index.ts index fc3aff176..3fd2fcc51 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -14,15 +14,15 @@ * limitations under the License. * */ -import { ClusterCommand } from './cluster.ts' -import { InitCommand } from './init.ts' -import { MirrorNodeCommand } from './mirror_node.ts' -import { NetworkCommand } from './network.ts' -import { NodeCommand } from './node/index.ts' -import { RelayCommand } from './relay.ts' -import { AccountCommand } from './account.ts' -import * as flags from './flags.ts' -import { type Opts } from '../types/index.ts' +import * as flags from './flags.js' +import { ClusterCommand } from './cluster.js' +import { InitCommand } from './init.js' +import { MirrorNodeCommand } from './mirror_node.js' +import { NetworkCommand } from './network.js' +import { NodeCommand } from './node/index.js' +import { RelayCommand } from './relay.js' +import { AccountCommand } from './account.js' +import { type Opts } from '../types/index.js' /** * Return a list of Yargs command builder to be exposed through CLI diff --git a/src/commands/init.ts b/src/commands/init.ts index 81d81e50f..c9d1b2fa8 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -16,12 +16,12 @@ */ import { Listr } from 'listr2' import path from 'path' -import { BaseCommand } from './base.ts' -import * as core from '../core/index.ts' -import { constants } from '../core/index.ts' +import { BaseCommand } from './base.js' +import * as core from '../core/index.js' +import { constants } from '../core/index.js' import * as fs from 'fs' -import { SoloError } from '../core/errors.ts' -import * as flags from './flags.ts' +import { SoloError } from '../core/errors.js' +import * as flags from './flags.js' import chalk from 'chalk' /** diff --git a/src/commands/mirror_node.ts b/src/commands/mirror_node.ts index 21facbd69..5fb64d354 100644 --- a/src/commands/mirror_node.ts +++ b/src/commands/mirror_node.ts @@ -16,14 +16,15 @@ */ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer' import { Listr } from 'listr2' -import { SoloError, IllegalArgumentError, MissingArgumentError } from '../core/errors.ts' -import { constants, type ProfileManager, type AccountManager } from '../core/index.ts' -import { BaseCommand } from './base.ts' -import * as flags from './flags.ts' -import * as prompts from './prompts.ts' -import { getFileContents, getEnvValue } from '../core/helpers.ts' -import { type PodName } from '../types/aliases.ts' -import { type Opts } from '../types/index.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from '../core/errors.js' +import { constants, type ProfileManager, type AccountManager } from '../core/index.js' +import { BaseCommand } from './base.js' +import * as flags from './flags.js' +import * as prompts from './prompts.js' +import { getFileContents, getEnvValue } from '../core/helpers.js' +import { type PodName } from '../types/aliases.js' +import { type Opts } from '../types/index.js' +import { ListrLease } from '../core/lease/listr_lease.js' export class MirrorNodeCommand extends BaseCommand { private readonly accountManager: AccountManager @@ -129,7 +130,7 @@ export class MirrorNodeCommand extends BaseCommand { async deploy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface MirrorNodeDeployConfigClass { chartDirectory: string @@ -191,7 +192,7 @@ export class MirrorNodeCommand extends BaseCommand { await self.accountManager.loadNodeClient(ctx.config.namespace) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { @@ -350,7 +351,7 @@ export class MirrorNodeCommand extends BaseCommand { async destroy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: { @@ -393,7 +394,7 @@ export class MirrorNodeCommand extends BaseCommand { await self.accountManager.loadNodeClient(ctx.config.namespace) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { diff --git a/src/commands/network.ts b/src/commands/network.ts index 05636d830..5b4cc623d 100644 --- a/src/commands/network.ts +++ b/src/commands/network.ts @@ -17,18 +17,19 @@ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer' import chalk from 'chalk' import { Listr } from 'listr2' -import { SoloError, IllegalArgumentError, MissingArgumentError } from '../core/errors.ts' -import { BaseCommand } from './base.ts' -import * as flags from './flags.ts' -import { constants, Templates } from '../core/index.ts' -import * as prompts from './prompts.ts' -import * as helpers from '../core/helpers.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from '../core/errors.js' +import { BaseCommand } from './base.js' +import * as flags from './flags.js' +import { constants, Templates } from '../core/index.js' +import * as prompts from './prompts.js' +import * as helpers from '../core/helpers.js' import path from 'path' -import { addDebugOptions, validatePath } from '../core/helpers.ts' +import { addDebugOptions, validatePath } from '../core/helpers.js' import fs from 'fs' -import type { CertificateManager, KeyManager, PlatformInstaller, ProfileManager } from '../core/index.ts' -import type { NodeAlias, NodeAliases } from '../types/aliases.ts' -import type { Opts } from '../types/index.ts' +import type { CertificateManager, KeyManager, PlatformInstaller, ProfileManager } from '../core/index.js' +import type { NodeAlias, NodeAliases } from '../types/aliases.js' +import type { Opts } from '../types/index.js' +import { ListrLease } from '../core/lease/listr_lease.js' export interface NetworkDeployConfigClass { applicationEnv: string @@ -230,7 +231,7 @@ export class NetworkCommand extends BaseCommand { /** Run helm install and deploy network components */ async deploy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: NetworkDeployConfigClass @@ -241,7 +242,7 @@ export class NetworkCommand extends BaseCommand { title: 'Initialize', task: async (ctx, task) => { ctx.config = await self.prepareConfig(task, argv) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { @@ -429,7 +430,7 @@ export class NetworkCommand extends BaseCommand { async destroy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: { @@ -468,7 +469,7 @@ export class NetworkCommand extends BaseCommand { namespace: self.configManager.getFlag(flags.namespace) as string } - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { @@ -522,7 +523,7 @@ export class NetworkCommand extends BaseCommand { /** Run helm upgrade to refresh network components with new settings */ async refresh (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface Context { config: NetworkDeployConfigClass @@ -533,7 +534,7 @@ export class NetworkCommand extends BaseCommand { title: 'Initialize', task: async (ctx, task) => { ctx.config = await self.prepareConfig(task, argv) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { diff --git a/src/commands/node/configs.ts b/src/commands/node/configs.ts index 4b14ad502..4fb56f996 100644 --- a/src/commands/node/configs.ts +++ b/src/commands/node/configs.ts @@ -14,17 +14,17 @@ * limitations under the License. * */ -import { FREEZE_ADMIN_ACCOUNT } from '../../core/constants.ts' -import { constants, Templates } from '../../core/index.ts' +import { FREEZE_ADMIN_ACCOUNT } from '../../core/constants.js' +import { constants, Templates } from '../../core/index.js' import { PrivateKey } from '@hashgraph/sdk' -import { SoloError } from '../../core/errors.ts' -import * as helpers from '../../core/helpers.ts' +import { SoloError } from '../../core/errors.js' +import * as helpers from '../../core/helpers.js' import path from 'path' import fs from 'fs' -import { validatePath } from '../../core/helpers.ts' -import * as flags from '../flags.ts' -import { type NodeAlias, type NodeAliases, type PodName } from '../../types/aliases.ts' -import { type NetworkNodeServices } from '../../core/network_node_services.ts' +import { validatePath } from '../../core/helpers.js' +import * as flags from '../flags.js' +import { type NodeAlias, type NodeAliases, type PodName } from '../../types/aliases.js' +import { type NetworkNodeServices } from '../../core/network_node_services.js' export const PREPARE_UPGRADE_CONFIGS_NAME = 'prepareUpgradeConfig' export const DOWNLOAD_GENERATED_FILES_CONFIGS_NAME = 'downloadGeneratedFilesConfig' @@ -485,4 +485,4 @@ export interface NodeUpdateConfigClass { treasuryKey: PrivateKey getUnusedConfigs: () => string[] curDate: Date -} \ No newline at end of file +} diff --git a/src/commands/node/flags.ts b/src/commands/node/flags.ts index 9fc60789f..231016a7c 100644 --- a/src/commands/node/flags.ts +++ b/src/commands/node/flags.ts @@ -14,8 +14,8 @@ * limitations under the License. * */ +import { flags } from '../index.js' -import * as flags from '../flags.ts' export const DEFAULT_FLAGS = { requiredFlags: [], diff --git a/src/commands/node/handlers.ts b/src/commands/node/handlers.ts index 610b0ab53..dda674156 100644 --- a/src/commands/node/handlers.ts +++ b/src/commands/node/handlers.ts @@ -15,13 +15,13 @@ * */ -import * as helpers from '../../core/helpers.ts' -import * as NodeFlags from './flags.ts' +import * as helpers from '../../core/helpers.js' +import * as NodeFlags from './flags.js' import { addConfigBuilder, deleteConfigBuilder, downloadGeneratedFilesConfigBuilder, keysConfigBuilder, logsConfigBuilder, prepareUpgradeConfigBuilder, refreshConfigBuilder, setupConfigBuilder, startConfigBuilder, stopConfigBuilder, updateConfigBuilder -} from './configs.ts' +} from './configs.js' import { type ConfigManager, constants, @@ -29,12 +29,12 @@ import { type PlatformInstaller, type AccountManager, type LeaseManager -} from '../../core/index.ts' -import { IllegalArgumentError } from '../../core/errors.ts' -import type { SoloLogger } from '../../core/logging.ts' -import type { NodeCommand } from './index.ts' -import type { NodeCommandTasks } from './tasks.ts' -import type { LeaseWrapper } from '../../core/lease_wrapper.ts' +} from '../../core/index.js' +import { IllegalArgumentError } from '../../core/errors.js' +import type { SoloLogger } from '../../core/logging.js' +import type { NodeCommand } from './index.js' +import type { NodeCommandTasks } from './tasks.js' +import { type Lease } from '../../core/lease/lease.js' export class NodeCommandHandlers { private readonly accountManager: AccountManager @@ -88,7 +88,7 @@ export class NodeCommandHandlers { /** ******** Task Lists **********/ - deletePrepareTaskList (argv: any, lease: LeaseWrapper) { + deletePrepareTaskList (argv: any, lease: Lease) { return [ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease), this.tasks.identifyExistingNodes(), @@ -131,7 +131,7 @@ export class NodeCommandHandlers { ] } - addPrepareTasks (argv: any, lease: LeaseWrapper) { + addPrepareTasks (argv: any, lease: Lease) { return [ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease), this.tasks.checkPVCsEnabled(), @@ -182,7 +182,7 @@ export class NodeCommandHandlers { ] } - updatePrepareTasks (argv, lease: LeaseWrapper) { + updatePrepareTasks (argv, lease: Lease) { return [ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease), this.tasks.identifyExistingNodes(), @@ -229,7 +229,7 @@ export class NodeCommandHandlers { async prepareUpgrade (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DEFAULT_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, prepareUpgradeConfigBuilder.bind(this), lease), @@ -264,7 +264,7 @@ export class NodeCommandHandlers { async downloadGeneratedFiles (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DEFAULT_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, downloadGeneratedFilesConfigBuilder.bind(this), lease), @@ -282,7 +282,7 @@ export class NodeCommandHandlers { async update (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.updatePrepareTasks(argv, lease), @@ -299,7 +299,7 @@ export class NodeCommandHandlers { async updatePrepare (argv) { argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_PREPARE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.updatePrepareTasks(argv, lease), @@ -314,7 +314,7 @@ export class NodeCommandHandlers { } async updateSubmitTransactions (argv) { - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_SUBMIT_TRANSACTIONS_FLAGS) const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease), @@ -330,7 +330,7 @@ export class NodeCommandHandlers { } async updateExecute (argv) { - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() argv = helpers.addFlagsToArgv(argv, NodeFlags.UPDATE_EXECUTE_FLAGS) const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, updateConfigBuilder.bind(this), lease), @@ -347,7 +347,7 @@ export class NodeCommandHandlers { async delete (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.deletePrepareTaskList(argv, lease), ...this.deleteSubmitTransactionsTaskList(argv), @@ -364,7 +364,7 @@ export class NodeCommandHandlers { async deletePrepare (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_PREPARE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.deletePrepareTaskList(argv, lease), @@ -381,7 +381,7 @@ export class NodeCommandHandlers { async deleteSubmitTransactions (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_SUBMIT_TRANSACTIONS_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease), @@ -399,7 +399,7 @@ export class NodeCommandHandlers { async deleteExecute (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.DELETE_EXECUTE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, deleteConfigBuilder.bind(this), lease), @@ -417,7 +417,7 @@ export class NodeCommandHandlers { async add (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.addPrepareTasks(argv, lease), @@ -435,7 +435,7 @@ export class NodeCommandHandlers { async addPrepare (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_PREPARE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ ...this.addPrepareTasks(argv, lease), @@ -452,7 +452,7 @@ export class NodeCommandHandlers { async addSubmitTransactions (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_SUBMIT_TRANSACTIONS_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease), @@ -470,7 +470,7 @@ export class NodeCommandHandlers { async addExecute (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.ADD_EXECUTE_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, addConfigBuilder.bind(this), lease), @@ -503,7 +503,7 @@ export class NodeCommandHandlers { async refresh (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.REFRESH_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, refreshConfigBuilder.bind(this), lease), @@ -526,17 +526,15 @@ export class NodeCommandHandlers { async keys (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.KEYS_FLAGS) - const lease = this.leaseManager.instantiateLease() - const action = helpers.commandActionBuilder([ - this.tasks.initialize(argv, keysConfigBuilder.bind(this), lease), + this.tasks.initialize(argv, keysConfigBuilder.bind(this), null), this.tasks.generateGossipKeys(), this.tasks.generateGrpcTlsKeys(), this.tasks.finalize() ], { concurrent: false, rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION - }, 'Error generating keys', lease) + }, 'Error generating keys', null) await action(argv, this) return true @@ -545,7 +543,7 @@ export class NodeCommandHandlers { async stop (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.STOP_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, stopConfigBuilder.bind(this), lease), @@ -563,7 +561,7 @@ export class NodeCommandHandlers { async start (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.START_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, startConfigBuilder.bind(this), lease), @@ -585,7 +583,7 @@ export class NodeCommandHandlers { async setup (argv: any) { argv = helpers.addFlagsToArgv(argv, NodeFlags.SETUP_FLAGS) - const lease = this.leaseManager.instantiateLease() + const lease = await this.leaseManager.create() const action = helpers.commandActionBuilder([ this.tasks.initialize(argv, setupConfigBuilder.bind(this), lease), diff --git a/src/commands/node/index.ts b/src/commands/node/index.ts index 0addc10c9..6f0afbfa6 100644 --- a/src/commands/node/index.ts +++ b/src/commands/node/index.ts @@ -15,13 +15,13 @@ * */ -import { IllegalArgumentError } from '../../core/errors.ts' -import { type AccountManager, YargsCommand } from '../../core/index.ts' -import { BaseCommand } from './../base.ts' -import { NodeCommandTasks } from './tasks.ts' -import * as NodeFlags from './flags.ts' -import { NodeCommandHandlers } from './handlers.ts' -import type { Opts } from '../../types/index.ts' +import { IllegalArgumentError } from '../../core/errors.js' +import { type AccountManager, YargsCommand } from '../../core/index.js' +import { BaseCommand } from './../base.js' +import { NodeCommandTasks } from './tasks.js' +import * as NodeFlags from './flags.js' +import { NodeCommandHandlers } from './handlers.js' +import type { Opts } from '../../types/index.js' /** * Defines the core functionalities of 'node' command diff --git a/src/commands/node/tasks.ts b/src/commands/node/tasks.ts index f97de1232..f0c8b0381 100644 --- a/src/commands/node/tasks.ts +++ b/src/commands/node/tasks.ts @@ -26,7 +26,7 @@ import { Zippy, type AccountManager, type CertificateManager -} from '../../core/index.ts' +} from '../../core/index.js' import { DEFAULT_NETWORK_NODE_NAME, FREEZE_ADMIN_ACCOUNT, @@ -34,7 +34,7 @@ import { LOCAL_HOST, SECONDS, TREASURY_ACCOUNT_ID -} from '../../core/constants.ts' +} from '../../core/constants.js' import { AccountBalanceQuery, AccountId, AccountUpdateTransaction, FileAppendTransaction, @@ -47,8 +47,8 @@ import { NodeUpdateTransaction, Timestamp } from '@hashgraph/sdk' -import { IllegalArgumentError, MissingArgumentError, SoloError } from '../../core/errors.ts' -import * as prompts from '../prompts.ts' +import { IllegalArgumentError, MissingArgumentError, SoloError } from '../../core/errors.js' +import * as prompts from '../prompts.js' import path from 'path' import fs from 'fs' import crypto from 'crypto' @@ -60,18 +60,19 @@ import { renameAndCopyFile, sleep, splitFlagInput -} from '../../core/helpers.ts' +} from '../../core/helpers.js' import chalk from 'chalk' -import * as flags from '../flags.ts' -import { type SoloLogger } from '../../core/logging.ts' +import * as flags from '../flags.js' +import { type SoloLogger } from '../../core/logging.js' import type { Listr, ListrTaskWrapper } from 'listr2' -import { type NodeAlias, type NodeAliases, type PodName } from '../../types/aliases.ts' -import { NodeStatusCodes, NodeStatusEnums } from '../../core/enumerations.ts' +import { type NodeAlias, type NodeAliases, type PodName } from '../../types/aliases.js' +import { NodeStatusCodes, NodeStatusEnums } from '../../core/enumerations.js' import * as x509 from '@peculiar/x509' -import { type NodeCommand } from './index.ts' -import type { NodeDeleteConfigClass, NodeRefreshConfigClass, NodeUpdateConfigClass } from './configs.ts' -import type { NodeAddConfigClass } from './configs.ts' -import type { LeaseWrapper } from '../../core/lease_wrapper.ts' +import { type NodeCommand } from './index.js' +import type { NodeDeleteConfigClass, NodeRefreshConfigClass, NodeUpdateConfigClass } from './configs.js' +import type { NodeAddConfigClass } from './configs.js' +import { type Lease } from '../../core/lease/lease.js' +import { ListrLease } from '../../core/lease/listr_lease.js' export class NodeCommandTasks { private readonly accountManager: AccountManager @@ -673,9 +674,9 @@ export class NodeCommandTasks { if (localBuildPath !== '') { return this._uploadPlatformSoftware(ctx.config[aliasesField], podNames, task, localBuildPath) - } + } return this._fetchPlatformSoftware(ctx.config[aliasesField], podNames, releaseTag, task, this.platformInstaller) - + }) } @@ -1328,7 +1329,7 @@ export class NodeCommandTasks { }) } - initialize (argv: any, configInit: Function, lease: LeaseWrapper | null) { + initialize (argv: any, configInit: Function, lease: Lease | null) { const { requiredFlags, requiredFlagsWithDisabledPrompt, optionalFlags } = argv const allRequiredFlags = [ ...requiredFlags, @@ -1373,7 +1374,9 @@ export class NodeCommandTasks { this.logger.debug('Initialized config', { config }) - if (lease) return lease.buildAcquireTask(task) + if (lease) { + return ListrLease.newAcquireLeaseTask(lease, task) + } }) } } diff --git a/src/commands/prompts.ts b/src/commands/prompts.ts index f45d04901..ff8a175be 100644 --- a/src/commands/prompts.ts +++ b/src/commands/prompts.ts @@ -16,13 +16,13 @@ */ import { ListrEnquirerPromptAdapter } from '@listr2/prompt-adapter-enquirer' import fs from 'fs' -import { SoloError, IllegalArgumentError } from '../core/errors.ts' -import { ConfigManager, constants } from '../core/index.ts' -import * as flags from './flags.ts' -import * as helpers from '../core/helpers.ts' -import { hederaExplorerVersion, resetDisabledPrompts } from './flags.ts' +import { SoloError, IllegalArgumentError } from '../core/errors.js' +import { ConfigManager, constants } from '../core/index.js' +import * as flags from './flags.js' +import * as helpers from '../core/helpers.js' +import { hederaExplorerVersion, resetDisabledPrompts } from './flags.js' import type { ListrTaskWrapper } from 'listr2' -import { type CommandFlag } from '../types/index.ts' +import { type CommandFlag } from '../types/index.js' async function prompt (type: string, task: ListrTaskWrapper, input: any, defaultValue: any, promptMessage: string, emptyCheckMessage: string | null, flagName: string) { try { diff --git a/src/commands/relay.ts b/src/commands/relay.ts index 0ab85b9a1..39ce73ac3 100644 --- a/src/commands/relay.ts +++ b/src/commands/relay.ts @@ -15,16 +15,17 @@ * */ import { Listr } from 'listr2' -import { SoloError, MissingArgumentError } from '../core/errors.ts' -import * as helpers from '../core/helpers.ts' -import type { ProfileManager, AccountManager } from '../core/index.ts' -import { constants } from '../core/index.ts' -import { BaseCommand } from './base.ts' -import * as flags from './flags.ts' -import * as prompts from './prompts.ts' -import { getNodeAccountMap } from '../core/helpers.ts' -import { type NodeAliases } from '../types/aliases.ts' -import { type Opts } from '../types/index.ts' +import { SoloError, MissingArgumentError } from '../core/errors.js' +import * as helpers from '../core/helpers.js' +import type { ProfileManager, AccountManager } from '../core/index.js' +import { constants } from '../core/index.js' +import { BaseCommand } from './base.js' +import * as flags from './flags.js' +import * as prompts from './prompts.js' +import { getNodeAccountMap } from '../core/helpers.js' +import { type NodeAliases } from '../types/aliases.js' +import { type Opts } from '../types/index.js' +import { ListrLease } from '../core/lease/listr_lease.js' export class RelayCommand extends BaseCommand { private readonly profileManager: ProfileManager @@ -157,7 +158,7 @@ export class RelayCommand extends BaseCommand { async deploy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface RelayDeployConfigClass { chainId: string @@ -204,7 +205,7 @@ export class RelayCommand extends BaseCommand { self.logger.debug('Initialized config', { config: ctx.config }) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { @@ -272,7 +273,7 @@ export class RelayCommand extends BaseCommand { async destroy (argv: any) { const self = this - const lease = self.leaseManager.instantiateLease() + const lease = await self.leaseManager.create() interface RelayDestroyConfigClass { chartDirectory: string @@ -308,7 +309,7 @@ export class RelayCommand extends BaseCommand { self.logger.debug('Initialized config', { config: ctx.config }) - return lease.buildAcquireTask(task) + return ListrLease.newAcquireLeaseTask(lease, task) } }, { diff --git a/src/core/account_manager.ts b/src/core/account_manager.ts index dbc7f4487..f09eeaeef 100644 --- a/src/core/account_manager.ts +++ b/src/core/account_manager.ts @@ -16,7 +16,7 @@ */ import * as Base64 from 'js-base64' import os from 'os' -import * as constants from './constants.ts' +import * as constants from './constants.js' import type { Key } from '@hashgraph/sdk' import { AccountCreateTransaction, @@ -35,17 +35,17 @@ import { Status, TransferTransaction } from '@hashgraph/sdk' -import { SoloError, MissingArgumentError } from './errors.ts' -import { Templates } from './templates.ts' +import { SoloError, MissingArgumentError } from './errors.js' +import { Templates } from './templates.js' import ip from 'ip' -import type { NetworkNodeServices } from './network_node_services.ts' -import { NetworkNodeServicesBuilder } from './network_node_services.ts' +import type { NetworkNodeServices } from './network_node_services.js' +import { NetworkNodeServicesBuilder } from './network_node_services.js' import path from 'path' -import { type SoloLogger } from './logging.ts' -import { type K8 } from './k8.ts' -import { type AccountIdWithKeyPairObject, type ExtendedNetServer } from '../types/index.ts' -import { type NodeAlias, type PodName } from '../types/aliases.ts' +import { type SoloLogger } from './logging.js' +import { type K8 } from './k8.js' +import { type AccountIdWithKeyPairObject, type ExtendedNetServer } from '../types/index.js' +import { type NodeAlias, type PodName } from '../types/aliases.js' const REASON_FAILED_TO_GET_KEYS = 'failed to get keys for accountId' const REASON_SKIPPED = 'skipped since it does not have a genesis key' diff --git a/src/core/certificate_manager.ts b/src/core/certificate_manager.ts index 6a5da4a18..5d6051d1b 100644 --- a/src/core/certificate_manager.ts +++ b/src/core/certificate_manager.ts @@ -14,17 +14,17 @@ * limitations under the License. * */ -import { MissingArgumentError, SoloError } from './errors.ts' -import { flags } from '../commands/index.ts' +import { MissingArgumentError, SoloError } from './errors.js' +import { flags } from '../commands/index.js' import fs from 'fs' -import { Templates } from './templates.ts' -import { GrpcProxyTlsEnums } from './enumerations.ts' +import { Templates } from './templates.js' +import { GrpcProxyTlsEnums } from './enumerations.js' -import type { ConfigManager } from './config_manager.ts' -import type { K8 } from './k8.ts' -import type { SoloLogger } from './logging.ts' +import type { ConfigManager } from './config_manager.js' +import type { K8 } from './k8.js' +import type { SoloLogger } from './logging.js' import type { ListrTaskWrapper } from 'listr2' -import type { NodeAlias } from '../types/aliases.ts' +import type { NodeAlias } from '../types/aliases.js' /** * Used to handle interactions with certificates data and inject it into the K8s cluster secrets diff --git a/src/core/chart_manager.ts b/src/core/chart_manager.ts index 5a374d959..e7fc1f01f 100644 --- a/src/core/chart_manager.ts +++ b/src/core/chart_manager.ts @@ -14,10 +14,10 @@ * limitations under the License. * */ -import { constants, type Helm } from './index.ts' +import { constants, type Helm } from './index.js' import chalk from 'chalk' -import { SoloError } from './errors.ts' -import { type SoloLogger } from './logging.ts' +import { SoloError } from './errors.js' +import { type SoloLogger } from './logging.js' export class ChartManager { constructor (private readonly helm: Helm, private readonly logger: SoloLogger) { diff --git a/src/core/config_manager.ts b/src/core/config_manager.ts index 99d0b9633..cde1d143f 100644 --- a/src/core/config_manager.ts +++ b/src/core/config_manager.ts @@ -14,13 +14,13 @@ * limitations under the License. * */ -import { SoloError, MissingArgumentError } from './errors.ts' -import { SoloLogger } from './logging.ts' -import * as flags from '../commands/flags.ts' +import { SoloError, MissingArgumentError } from './errors.js' +import { SoloLogger } from './logging.js' +import * as flags from '../commands/flags.js' import * as paths from 'path' -import * as helpers from './helpers.ts' +import * as helpers from './helpers.js' import type * as yargs from 'yargs' -import { type CommandFlag } from '../types/index.ts' +import { type CommandFlag } from '../types/index.js' /** * ConfigManager cache command flag values so that user doesn't need to enter the same values repeatedly. diff --git a/src/core/constants.ts b/src/core/constants.ts index 92e8e3e46..7f8bad2b9 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -164,10 +164,6 @@ export const JVM_DEBUG_PORT = 5005 export const SECONDS = 1000 export const MINUTES = 60 * SECONDS -export const LEASE_ACQUIRE_RETRY_TIMEOUT = +process.env.LEASE_ACQUIRE_RETRY_TIMEOUT || 20 * SECONDS -export const MAX_LEASE_ACQUIRE_ATTEMPTS = +process.env.MAX_LEASE_ACQUIRE_ATTEMPTS || 10 -export const DEFAULT_LEASE_RENEW_TIMEOUT = 10 * SECONDS - export const PODS_RUNNING_MAX_ATTEMPTS = +process.env.PODS_RUNNING_MAX_ATTEMPTS || 60 * 15 export const PODS_RUNNING_DELAY = +process.env.PODS_RUNNING_DELAY || 1000 export const NETWORK_NODE_ACTIVE_MAX_ATTEMPTS = +process.env.NETWORK_NODE_ACTIVE_MAX_ATTEMPTS || 120 diff --git a/src/core/dependency_managers/dependency_manager.ts b/src/core/dependency_managers/dependency_manager.ts index 0bd9dba3b..5230398d2 100644 --- a/src/core/dependency_managers/dependency_manager.ts +++ b/src/core/dependency_managers/dependency_manager.ts @@ -15,10 +15,10 @@ * */ import os from 'os' -import { SoloError, MissingArgumentError } from '../errors.ts' -import { ShellRunner } from '../shell_runner.ts' -import { type SoloLogger } from '../logging.ts' -import { type HelmDependencyManager } from './helm_dependency_manager.ts' +import { SoloError, MissingArgumentError } from '../errors.js' +import { ShellRunner } from '../shell_runner.js' +import { type SoloLogger } from '../logging.js' +import { type HelmDependencyManager } from './helm_dependency_manager.js' import { type ListrTask } from 'listr2' export class DependencyManager extends ShellRunner { diff --git a/src/core/dependency_managers/helm_dependency_manager.ts b/src/core/dependency_managers/helm_dependency_manager.ts index b77b16533..c7bb56643 100644 --- a/src/core/dependency_managers/helm_dependency_manager.ts +++ b/src/core/dependency_managers/helm_dependency_manager.ts @@ -18,14 +18,14 @@ import fs from 'fs' import os from 'os' import path from 'path' import * as util from 'util' -import { IllegalArgumentError, MissingArgumentError } from '../errors.ts' -import * as helpers from '../helpers.ts' -import { constants, type PackageDownloader, Templates, type Zippy } from '../index.ts' -import * as version from '../../../version.ts' -import { ShellRunner } from '../shell_runner.ts' +import { IllegalArgumentError, MissingArgumentError } from '../errors.js' +import * as helpers from '../helpers.js' +import { constants, type PackageDownloader, Templates, type Zippy } from '../index.js' +import * as version from '../../../version.js' +import { ShellRunner } from '../shell_runner.js' import * as semver from 'semver' -import { OS_WIN32, OS_WINDOWS } from '../constants.ts' -import { type SoloLogger } from '../logging.ts' +import { OS_WIN32, OS_WINDOWS } from '../constants.js' +import { type SoloLogger } from '../logging.js' // constants required by HelmDependencyManager const HELM_RELEASE_BASE_URL = 'https://get.helm.sh' diff --git a/src/core/dependency_managers/index.ts b/src/core/dependency_managers/index.ts index 170033500..08b56f4f7 100644 --- a/src/core/dependency_managers/index.ts +++ b/src/core/dependency_managers/index.ts @@ -14,7 +14,7 @@ * limitations under the License. * */ -import { DependencyManager } from './dependency_manager.ts' -import { HelmDependencyManager } from './helm_dependency_manager.ts' +import { DependencyManager } from './dependency_manager.js' +import { HelmDependencyManager } from './helm_dependency_manager.js' export { HelmDependencyManager, DependencyManager } diff --git a/src/core/helm.ts b/src/core/helm.ts index ea3fc6c78..a6f26676b 100644 --- a/src/core/helm.ts +++ b/src/core/helm.ts @@ -15,11 +15,11 @@ * */ import os from 'os' -import { constants } from './index.ts' -import { ShellRunner } from './shell_runner.ts' -import { Templates } from './templates.ts' -import { IllegalArgumentError } from './errors.ts' -import type { SoloLogger } from './logging.ts' +import { constants } from './index.js' +import { ShellRunner } from './shell_runner.js' +import { Templates } from './templates.js' +import { IllegalArgumentError } from './errors.js' +import type { SoloLogger } from './logging.js' export class Helm extends ShellRunner { private readonly helmPath: string diff --git a/src/core/helpers.ts b/src/core/helpers.ts index f05682077..c50e4e02d 100644 --- a/src/core/helpers.ts +++ b/src/core/helpers.ts @@ -18,21 +18,21 @@ import fs from 'fs' import os from 'os' import path from 'path' import util from 'util' -import { SoloError } from './errors.ts' +import { SoloError } from './errors.js' import * as semver from 'semver' -import { Templates } from './templates.ts' -import { HEDERA_HAPI_PATH, ROOT_CONTAINER, ROOT_DIR, SOLO_LOGS_DIR } from './constants.ts' -import { constants, type K8 } from './index.ts' +import { Templates } from './templates.js' +import { HEDERA_HAPI_PATH, ROOT_CONTAINER, ROOT_DIR, SOLO_LOGS_DIR } from './constants.js' +import { constants, type K8 } from './index.js' import { FileContentsQuery, FileId, PrivateKey, ServiceEndpoint } from '@hashgraph/sdk' import { Listr } from 'listr2' -import { type AccountManager } from './account_manager.ts' -import { type NodeAlias, type NodeAliases, type PodName } from '../types/aliases.ts' -import { type NodeDeleteConfigClass, type NodeUpdateConfigClass } from '../commands/node/configs.ts' -import { type CommandFlag } from '../types/index.ts' +import { type AccountManager } from './account_manager.js' +import { type NodeAlias, type NodeAliases, type PodName } from '../types/aliases.js' +import { type NodeDeleteConfigClass, type NodeUpdateConfigClass } from '../commands/node/configs.js' +import { type CommandFlag } from '../types/index.js' import { type V1Pod } from '@kubernetes/client-node' -import { type SoloLogger } from './logging.ts' -import { type NodeCommandHandlers } from '../commands/node/handlers.ts' -import { type LeaseWrapper } from './lease_wrapper.ts' +import { type SoloLogger } from './logging.js' +import { type NodeCommandHandlers } from '../commands/node/handlers.js' +import { type Lease } from './lease/lease.js' export function sleep (ms: number) { return new Promise((resolve) => { @@ -465,7 +465,7 @@ export function prepareEndpoints (endpointType: string, endpoints: string[], def return ret } -export function commandActionBuilder (actionTasks: any, options: any, errorString: string, lease: LeaseWrapper | null) { +export function commandActionBuilder (actionTasks: any, options: any, errorString: string, lease: Lease | null) { return async function (argv: any, commandDef: NodeCommandHandlers) { const tasks = new Listr([ ...actionTasks diff --git a/src/core/index.ts b/src/core/index.ts index 882aa4dfe..122fae85e 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -14,25 +14,25 @@ * limitations under the License. * */ -import * as logging from './logging.ts' -import * as constants from './constants.ts' -import { Helm } from './helm.ts' -import { K8 } from './k8.ts' -import { PackageDownloader } from './package_downloader.ts' -import { PlatformInstaller } from './platform_installer.ts' -import { Zippy } from './zippy.ts' -import { Templates } from './templates.ts' -import { ChartManager } from './chart_manager.ts' -import { ConfigManager } from './config_manager.ts' -import { KeyManager } from './key_manager.ts' -import { ProfileManager } from './profile_manager.ts' -import { YargsCommand } from './yargs_command.ts' -import { Task } from './task.ts' -import * as helpers from './helpers.ts' -import { DependencyManager } from './dependency_managers/index.ts' -import { AccountManager } from './account_manager.ts' -import { LeaseManager } from './lease_manager.ts' -import { CertificateManager } from './certificate_manager.ts' +import * as logging from './logging.js' +import * as constants from './constants.js' +import { Helm } from './helm.js' +import { K8 } from './k8.js' +import { PackageDownloader } from './package_downloader.js' +import { PlatformInstaller } from './platform_installer.js' +import { Zippy } from './zippy.js' +import { Templates } from './templates.js' +import { ChartManager } from './chart_manager.js' +import { ConfigManager } from './config_manager.js' +import { KeyManager } from './key_manager.js' +import { ProfileManager } from './profile_manager.js' +import { YargsCommand } from './yargs_command.js' +import { Task } from './task.js' +import * as helpers from './helpers.js' +import { DependencyManager } from './dependency_managers/index.js' +import { AccountManager } from './account_manager.js' +import { LeaseManager } from './lease/lease_manager.js' +import { CertificateManager } from './certificate_manager.js' // Expose components from the core module export { diff --git a/src/core/k8.ts b/src/core/k8.ts index 24712b1cf..df3ec38ce 100644 --- a/src/core/k8.ts +++ b/src/core/k8.ts @@ -19,19 +19,19 @@ import fs from 'fs' import net from 'net' import os from 'os' import path from 'path' -import { flags } from '../commands/index.ts' -import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' +import { flags } from '../commands/index.js' +import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' import * as tar from 'tar' import { v4 as uuid4 } from 'uuid' -import { V1ObjectMeta, V1Secret } from '@kubernetes/client-node' -import { sleep } from './helpers.ts' -import { type ConfigManager, constants } from './index.ts' +import { type V1Lease, V1ObjectMeta, V1Secret } from '@kubernetes/client-node' +import { sleep } from './helpers.js' +import { type ConfigManager, constants } from './index.js' import * as stream from 'node:stream' -import { type SoloLogger } from './logging.ts' +import { type SoloLogger } from './logging.js' import type * as WebSocket from 'ws' -import type { PodName } from '../types/aliases.ts' -import type { ExtendedNetServer, LocalContextObject } from '../types/index.ts' +import type { PodName } from '../types/aliases.js' +import type { ExtendedNetServer, LocalContextObject } from '../types/index.js' import type * as http from 'node:http' interface TDirectoryData {directory: boolean; owner: string; group: string; size: string; modifiedAt: string; name: string} @@ -1150,7 +1150,7 @@ export class K8 { } // --------------------------------------- LEASES --------------------------------------- // - async createNamespacedLease (namespace: string, leaseName: string, holderName: string) { + async createNamespacedLease (namespace: string, leaseName: string, holderName: string, durationSeconds = 20) { const lease = new k8s.V1Lease() const metadata = new k8s.V1ObjectMeta() @@ -1160,7 +1160,7 @@ export class K8 { const spec = new k8s.V1LeaseSpec() spec.holderIdentity = holderName - spec.leaseDurationSeconds = 20 + spec.leaseDurationSeconds = durationSeconds spec.acquireTime = new k8s.V1MicroTime() lease.spec = spec @@ -1192,6 +1192,20 @@ export class K8 { return body as k8s.V1Lease } + async transferNamespaceLease (lease: k8s.V1Lease, newHolderName: string): Promise { + lease.spec.leaseTransitions++ + lease.spec.renewTime = new k8s.V1MicroTime() + lease.spec.holderIdentity = newHolderName + + const { response, body } = await this.coordinationApiClient + .replaceNamespacedLease(lease.metadata.name, lease.metadata.namespace, lease) + .catch(e => e) + + this._handleKubernetesClientError(response, body, 'Failed to transfer namespaced lease') + + return body as k8s.V1Lease + } + async deleteNamespacedLease (name: string, namespace: string) { const { response, body } = await this.coordinationApiClient.deleteNamespacedLease(name, namespace) .catch(e => e) diff --git a/src/core/key_manager.ts b/src/core/key_manager.ts index 7c43f2a67..425924ae6 100644 --- a/src/core/key_manager.ts +++ b/src/core/key_manager.ts @@ -18,14 +18,14 @@ import * as x509 from '@peculiar/x509' import crypto from 'crypto' import fs from 'fs' import path from 'path' -import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' -import { constants } from './index.ts' -import { SoloLogger } from './logging.ts' -import { Templates } from './templates.ts' -import * as helpers from './helpers.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' +import { constants } from './index.js' +import { SoloLogger } from './logging.js' +import { Templates } from './templates.js' +import * as helpers from './helpers.js' import chalk from 'chalk' -import { type NodeAlias, type NodeAliases } from '../types/aliases.ts' -import { type NodeKeyObject, type PrivateKeyAndCertificateObject } from '../types/index.ts' +import { type NodeAlias, type NodeAliases } from '../types/aliases.js' +import { type NodeKeyObject, type PrivateKeyAndCertificateObject } from '../types/index.js' import type { ListrTask } from 'listr2' // @ts-ignore diff --git a/src/core/lease/lease.ts b/src/core/lease/lease.ts new file mode 100644 index 000000000..62dabc6ec --- /dev/null +++ b/src/core/lease/lease.ts @@ -0,0 +1,389 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { MissingArgumentError, SoloError } from '../errors.js' +import { type V1Lease } from '@kubernetes/client-node' +import { type K8 } from '../k8.js' +import { SECONDS } from '../constants.js' +import { LeaseHolder } from './lease_holder.js' +import { LeaseAcquisitionError, LeaseRelinquishmentError } from './lease_errors.js' +import { type LeaseRenewalService } from './lease_renewal.js' +import { sleep } from '../helpers.js' + +/** + * Concrete implementation of a Kubernetes based time-based mutually exclusive lock via the Coordination API. + * Applies a namespace/deployment wide lock to ensure that only one process, machine, and user can hold the lease at a time. + * The lease is automatically renewed in the background to prevent expiration and ensure the holder maintains the lease. + * If the process die, the lease is automatically released after the lease duration. + * + * @public + */ +export class Lease { + /** The default duration in seconds for which the lease is to be held before being considered expired. */ + public static readonly DEFAULT_LEASE_DURATION = 20 + + /** The holder of the lease. */ + private readonly _leaseHolder: LeaseHolder + + /** The namespace which contains the lease. */ + private readonly _namespace: string + + /** The name of the lease. */ + private readonly _leaseName: string + + /** The duration in seconds for which the lease is to be held. */ + private readonly _durationSeconds: number + + /** The identifier of the scheduled lease renewal. */ + private _scheduleId: number | null = null + + /** + * @param client - Injected kubernetes client need by the methods to create, renew, and delete leases. + * @param renewalService - Injected lease renewal service need to support automatic (background) lease renewals. + * @param leaseHolder - The holder of the lease. + * @param namespace - The namespace in which the lease is to be acquired. + * @param leaseName - The name of the lease to be acquired; if not provided, the namespace is used. + * @param durationSeconds - The duration in seconds for which the lease is to be held; if not provided, the default value is used. + */ + public constructor (private readonly client: K8, + private readonly renewalService: LeaseRenewalService, + leaseHolder: LeaseHolder, + namespace: string, + leaseName: string | null = null, + durationSeconds: number | null = null) { + if (!client) throw new MissingArgumentError('client is required') + if (!renewalService) throw new MissingArgumentError('renewalService is required') + if (!leaseHolder) throw new MissingArgumentError('_leaseHolder is required') + if (!namespace) throw new MissingArgumentError('_namespace is required') + + this._leaseHolder = leaseHolder + this._namespace = namespace + + if (!leaseName) { + this._leaseName = this._namespace + } + + // In most production cases, the environment variable should be preferred over the constructor argument. + if (!durationSeconds) { + this._durationSeconds = +process.env.SOLO_LEASE_DURATION || Lease.DEFAULT_LEASE_DURATION + } else { + this._durationSeconds = durationSeconds + } + } + + /** + * The name of the lease. + */ + public get leaseName (): string { + return this._leaseName + } + + /** + * The holder of the lease. + */ + public get leaseHolder (): LeaseHolder { + return this._leaseHolder + } + + /** + * The namespace in which the lease is to be acquired. By default, the namespace is used as the lease name. + * The defaults assume there is only a single deployment in a given namespace. + */ + public get namespace (): string { + return this._namespace + } + + /** + * The duration in seconds for which the lease is held before being considered expired. By default, the duration + * is set to 20 seconds. It is recommended to renew the lease at 50% of the duration to prevent unexpected expiration. + */ + public get durationSeconds (): number { + return this._durationSeconds + } + + /** + * The identifier of the scheduled lease renewal task. + */ + public get scheduleId (): number | null { + return this._scheduleId + } + + /** + * Internal setter for the scheduleId property. External callers should not use this method. + * + * @param scheduleId - The identifier of the scheduled lease renewal task. + */ + private set scheduleId (scheduleId: number | null) { + this._scheduleId = scheduleId + } + + /** + * Acquires the lease. If the lease is already acquired, it checks if the lease is expired or held by the same process. + * If the lease is expired, it creates a new lease. If the lease is held by the same process, it renews the lease. + * If the lease is held by another process, then an exception is thrown. + * + * @throws LeaseAcquisitionError - If the lease is already acquired by another process or an error occurs during acquisition. + */ + public async acquire (): Promise { + const lease = await this.retrieveLease() + + if (!lease || Lease.checkExpiration(lease) || this.heldBySameProcess(lease)) { + return this.createOrRenewLease(lease) + } + + const otherHolder: LeaseHolder = LeaseHolder.fromJson(lease.spec.holderIdentity) + + if (this.heldBySameMachineIdentity(lease) && !otherHolder.isProcessAlive()) { + return await this.transferLease(lease) + } + + throw new LeaseAcquisitionError(`lease already acquired by '${otherHolder.username}' on the ` + + `'${otherHolder.hostname}' machine (PID: '${otherHolder.processId}')`, null, + { self: this.leaseHolder.toObject(), other: otherHolder.toObject() }) + } + + /** + * Attempts to acquire the lease, by calling the acquire method. If an exception is thrown, it is caught and false is returned. + * If the lease is successfully acquired, true is returned; otherwise, false is returned. + * + * @returns true if the lease is successfully acquired; otherwise, false. + */ + public async tryAcquire (): Promise { + try { + await this.acquire() + return true + } catch (e: SoloError | any) { + return false + } + } + + /** + * Renews the lease. If the lease is expired or held by the same process, it creates or renews the lease. + * If the lease is held by another process, then an exception is thrown. + * + * @throws LeaseAcquisitionError - If the lease is already acquired by another process or an error occurs during renewal. + */ + public async renew (): Promise { + const lease = await this.retrieveLease() + + if (!lease || this.heldBySameProcess(lease)) { + return await this.createOrRenewLease(lease) + } + + throw new LeaseAcquisitionError(`lease already acquired by '${this._leaseHolder.username}' on the ` + + `'${this._leaseHolder.hostname}' machine (PID: '${this._leaseHolder.processId}')`, null, + { self: this._leaseHolder.toObject(), other: this._leaseHolder.toObject() }) + } + + /** + * Attempts to renew the lease, by calling the renew method. If an exception is thrown, it is caught and false is returned. + * If the lease is successfully renewed, true is returned; otherwise, false is returned. + * + * @returns true if the lease is successfully renewed; otherwise, false. + */ + public async tryRenew (): Promise { + try { + await this.renew() + return true + } catch (e: SoloError | any) { + return false + } + } + + /** + * Releases the lease. If the lease is expired or held by the same process, it deletes the lease. + * If the lease is held by another process, then an exception is thrown. + * + * @throws LeaseRelinquishmentError - If the lease is already acquired by another process or an error occurs during relinquishment. + */ + public async release (): Promise { + const lease = await this.retrieveLease() + + if (this.scheduleId) { + await this.renewalService.cancel(this.scheduleId) + // Needed to ensure any pending renewals are truly cancelled before proceeding to delete the Lease. + // This is required because clearInterval() is not guaranteed to abort any pending interval. + await sleep(this.renewalService.calculateRenewalDelay(this)) + } + + this.scheduleId = null + + if (!lease) { + return + } + + const otherHolder: LeaseHolder = LeaseHolder.fromJson(lease.spec.holderIdentity) + + if (this.heldBySameProcess(lease) || Lease.checkExpiration(lease)) { + return await this.deleteLease() + } + + throw new LeaseRelinquishmentError(`lease already acquired by '${otherHolder.username}' on the ` + + `'${otherHolder.hostname}' machine (PID: '${otherHolder.processId}')`, null, + { self: this._leaseHolder.toObject(), other: otherHolder.toObject() }) + } + + /** + * Attempts to release the lease, by calling the release method. If an exception is thrown, it is caught and false is returned. + * If the lease is successfully released, true is returned; otherwise, false is returned. + * + * @returns true if the lease is successfully released; otherwise, false. + */ + public async tryRelease (): Promise { + try { + await this.release() + return true + } catch (e: SoloError | any) { + return false + } + } + + + /** + * Checks if the lease is acquired. If the lease is acquired and not expired, it returns true; otherwise, false. + * + * @returns true if the lease is acquired and not expired; otherwise, false. + */ + public async isAcquired (): Promise { + const lease = await this.retrieveLease() + return !!lease && !Lease.checkExpiration(lease) && this.heldBySameProcess(lease) + } + + /** + * Checks if the lease is expired. If the lease is expired, it returns true; otherwise, false. + * This method does not verify if the lease is acquired by the current process. + * + * @returns true if the lease is expired; otherwise, false. + */ + public async isExpired (): Promise { + const lease = await this.retrieveLease() + return !!lease && Lease.checkExpiration(lease) + } + + /** + * Retrieves the lease from the Kubernetes API server. + * + * @returns the Kubernetes lease object if it exists; otherwise, null. + * @throws LeaseAcquisitionError - If an error occurs during retrieval. + */ + private async retrieveLease (): Promise { + try { + return await this.client.readNamespacedLease(this.leaseName, this.namespace) + } catch (e: any) { + if (!(e instanceof SoloError)) { + throw new LeaseAcquisitionError(`failed to read the lease named '${this.leaseName}' in the ` + + `'${this.namespace}' namespace, caused by: ${e.message}`, e) + } + + if (e.meta.statusCode !== 404) { + throw new LeaseAcquisitionError('failed to read existing leases, unexpected server response of' + + `'${e.meta.statusCode}' received`, e) + } + } + + return null + } + + /** + * Creates or renews the lease. If the lease does not exist, it creates a new lease. If the lease exists, it renews the lease. + * + * @param lease - The lease to be created or renewed. + */ + private async createOrRenewLease (lease: V1Lease): Promise { + try { + if (!lease) { + await this.client.createNamespacedLease(this.leaseName, this.namespace, this.leaseHolder.toJson(), this.durationSeconds) + } else { + await this.client.renewNamespaceLease(this.leaseName, this.namespace, lease) + } + + if (!this.scheduleId) { + this.scheduleId = await this.renewalService.schedule(this) + } + } catch (e: any) { + throw new LeaseAcquisitionError(`failed to create or renew the lease named '${this.leaseName}' in the ` + + `'${this.namespace}' namespace`, e) + } + } + + /** + * Transfers an existing (expired) lease to the current process. + * + * @param lease - The lease to be transferred. + */ + private async transferLease (lease: V1Lease): Promise { + try { + await this.client.transferNamespaceLease(lease, this.leaseHolder.toJson()) + + if (!this.scheduleId) { + this.scheduleId = await this.renewalService.schedule(this) + } + } catch (e: any) { + throw new LeaseAcquisitionError(`failed to transfer the lease named '${this.leaseName}' in the ` + + `'${this.namespace}' namespace`, e) + } + } + + /** + * Deletes the lease from the Kubernetes API server. + */ + private async deleteLease (): Promise { + try { + await this.client.deleteNamespacedLease(this.leaseName, this.namespace) + } catch (e: any) { + throw new LeaseRelinquishmentError(`failed to delete the lease named '${this.leaseName}' in the ` + + `'${this.namespace}' namespace`, e) + } + } + + /** + * Determines if the lease has expired by comparing the delta in seconds between the current time and the last renewal time. + * + * @param lease - The lease to be checked for expiration. + * @returns true if the lease has expired; otherwise, false. + */ + private static checkExpiration (lease: V1Lease): boolean { + const now = Date.now() + const durationSec = lease.spec.leaseDurationSeconds || Lease.DEFAULT_LEASE_DURATION + const lastRenewal = lease.spec?.renewTime || lease.spec?.acquireTime + const deltaSec = (now - new Date(lastRenewal).valueOf()) / SECONDS + return deltaSec > durationSec + } + + /** + * Determines if the lease is held by the same process. This comparison is based on the user, machine, and + * process identifier of the leaseholder. + * + * @param lease - The lease to be checked for ownership. + * @returns true if the lease is held by the same process; otherwise, false. + */ + private heldBySameProcess (lease: V1Lease): boolean { + const holder: LeaseHolder = LeaseHolder.fromJson(lease.spec.holderIdentity) + return this.leaseHolder.equals(holder) + } + + /** + * Determines if the lease is held by the same machine identity. This comparison is based on the user and machine only. + * The process identifier is not considered in this comparison. + * + * @param lease - The lease to be checked for ownership. + * @returns true if the lease is held by the same user and machine; otherwise, false. + */ + private heldBySameMachineIdentity (lease: V1Lease): boolean { + const holder: LeaseHolder = LeaseHolder.fromJson(lease.spec.holderIdentity) + return this.leaseHolder.isSameMachineIdentity(holder) + } +} diff --git a/src/core/lease/lease_errors.ts b/src/core/lease/lease_errors.ts new file mode 100644 index 000000000..26ddc845c --- /dev/null +++ b/src/core/lease/lease_errors.ts @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { SoloError } from '../errors.js' + +export class LeaseAcquisitionError extends SoloError { + /** + * Instantiates a new error with a message and an optional cause. + * + * @param message - the error message to be reported. + * @param cause - optional underlying cause of the error. + * @param meta - optional metadata to be reported. + */ + public constructor (message: string, cause: Error | any = {}, meta: any = {}) { + super(message, cause, meta) + } +} + +export class LeaseRelinquishmentError extends SoloError { + /** + * Instantiates a new error with a message and an optional cause. + * + * @param message - the error message to be reported. + * @param cause - optional underlying cause of the error. + * @param meta - optional metadata to be reported. + */ + public constructor (message: string, cause: Error | any = {}, meta: any = {}) { + super(message, cause, meta) + } +} diff --git a/src/core/lease/lease_holder.ts b/src/core/lease/lease_holder.ts new file mode 100644 index 000000000..9f31fb2b3 --- /dev/null +++ b/src/core/lease/lease_holder.ts @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { MissingArgumentError } from '../errors.js' +import os from 'node:os' +import process from 'node:process' + +/** + * A representation of a leaseholder who is identified by a username, hostname, and process id (PID). This implementation + * is serializable to/from a JSON object and is comparable to other leaseholders. + */ +export class LeaseHolder { + /** The user's identity which is typically the OS login username. */ + private readonly _username: string + + /** The machine's identity which is typically the hostname. */ + private readonly _hostname: string + + /** The process identifier which is typically the OS PID. */ + private readonly _processId: number + + /** + * Constructs a new leaseholder with the given username, hostname, and process id. This constructor is private and + * should not be called directly. Use the static factory methods to create a new instance. + * + * @param username - the user's identity. + * @param hostname - the machine's identity. + * @param processId - the process identifier. + */ + private constructor (username: string, hostname: string, processId: number) { + if (!username) throw new MissingArgumentError('username is required') + if (!hostname) throw new MissingArgumentError('hostname is required') + if (!processId) throw new MissingArgumentError('pid is required') + + this._username = username + this._hostname = hostname + this._processId = processId + } + + /** + * Creates a new leaseholder with the given username. The hostname is set to the current machine's hostname and the + * process id is set to the current process's PID. + * @param username - the user's identity. + * @returns a new leaseholder instance. + */ + public static of (username: string): LeaseHolder { + return new LeaseHolder(username, os.hostname(), process.pid) + } + + /** + * Creates a new leaseholder by retrieving the current user's identity, the current machine's hostname, and the + * current process's PID. + * @returns a new leaseholder instance. + */ + public static default (): LeaseHolder { + return LeaseHolder.of(os.userInfo().username) + } + + /** + * The user's identity which is typically the OS login username. + * @returns the user's identity. + */ + public get username (): string { + return this._username + } + + + /** + * The machine's identity which is typically the hostname. + * @returns the machine's identity. + */ + public get hostname (): string { + return this._hostname + } + + /** + * The process identifier which is typically the OS PID. + * @returns the process identifier. + */ + public get processId (): number { + return this._processId + } + + /** + * Returns a plain object representation of this leaseholder. This object may be serialized to JSON. + * @returns a plain object representation of this leaseholder. + */ + public toObject (): any { + return { + username: this._username, + hostname: this._hostname, + pid: this._processId + } + } + + /** + * Compares this leaseholder to another leaseholder to determine if they are equal. Two leaseholders are equal if + * their username, hostname, and process id are the same. + * @param other - the other leaseholder to compare. + * @returns true if the leaseholders are equal; false otherwise. + */ + public equals (other: LeaseHolder): boolean { + return this.username === other.username && this.hostname === other.hostname && this.processId === other.processId + } + + /** + * Compares this leaseholder to another leaseholder to determine if they are the same machine. Two leaseholders are + * the same machine if their username and hostname are the same. + * @param other - the other leaseholder to compare. + * @returns true if the leaseholders are the same machine; false otherwise. + */ + public isSameMachineIdentity (other: LeaseHolder): boolean { + return this.username === other.username && this.hostname === other.hostname + } + + /** + * Determines if the process associated with this leaseholder is still alive. This method will return false if the + * process is not alive or an error occurs while checking the process status. + * @returns true if the process is alive; false otherwise. + */ + public isProcessAlive (): boolean { + try { + return process.kill(this.processId, 0) + } catch (e: any) { + return e.code === 'EPERM' + } + } + + /** + * Serializes this leaseholder to a JSON string representation. + * @returns a JSON string representation of this leaseholder. + */ + public toJson (): string { + return JSON.stringify(this.toObject()) + } + + /** + * Deserializes a JSON string representation of a leaseholder into a new leaseholder instance. + * @param json - the JSON string representation of a leaseholder. + * @returns a new leaseholder instance. + */ + public static fromJson (json: string): LeaseHolder { + const obj: ReturnType = JSON.parse(json) + return new LeaseHolder(obj.username, obj.hostname, obj.pid) + } +} diff --git a/src/core/lease/lease_manager.ts b/src/core/lease/lease_manager.ts new file mode 100644 index 000000000..2f4003818 --- /dev/null +++ b/src/core/lease/lease_manager.ts @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { MissingArgumentError } from '../errors.js' +import { flags } from '../../commands/index.js' +import type { ConfigManager } from '../config_manager.js' +import type { K8 } from '../k8.js' +import type { SoloLogger } from '../logging.js' +import { type LeaseRenewalService } from './lease_renewal.js' +import { Lease } from './lease.js' +import { LeaseHolder } from './lease_holder.js' +import { LeaseAcquisitionError } from './lease_errors.js' + +/** + * Manages the acquisition and renewal of leases. + */ +export class LeaseManager { + + /** The injected logger instance. */ + private readonly _logger: SoloLogger + + /** The injected lease renewal service instance. */ + private readonly _renewalService: LeaseRenewalService + + /** + * Creates a new lease manager. + * + * @param k8 - the Kubernetes client. + * @param configManager - the configuration manager. + * @param logger - the logger. + * @param renewalService - the lease renewal service. + */ + constructor ( + private readonly k8: K8, + private readonly configManager: ConfigManager, + logger: SoloLogger, + renewalService: LeaseRenewalService + ) { + if (!k8) throw new MissingArgumentError('an instance of core/K8 is required') + if (!logger) throw new MissingArgumentError('an instance of core/SoloLogger is required') + if (!configManager) throw new MissingArgumentError('an instance of core/ConfigManager is required') + if (!renewalService) throw new MissingArgumentError('an instance of core/LeaseRenewalService is required') + + this._logger = logger + this._renewalService = renewalService + } + + /** + * Creates a new lease. This lease is not acquired until the `acquire` method is called. + * + * @returns a new lease instance. + */ + public async create (): Promise { + return new Lease(this.k8, this._renewalService, LeaseHolder.default(), await this.currentNamespace()) + } + + /** + * Retrieves the renewal service implementation. + * + * @returns the lease renewal service. + */ + public get renewalService (): LeaseRenewalService { + return this._renewalService + } + + /** + * Retrieves the logger instance. + * + * @returns the logger. + */ + public get logger (): SoloLogger { + return this._logger + } + + /** + * Retrieves the user or configuration supplied namespace to use for lease acquisition. + * + * @returns the namespace to use for lease acquisition or null if no namespace is specified. + * @throws LeaseAcquisitionError if the namespace does not exist and cannot be created. + */ + private async currentNamespace (): Promise { + const deploymentNamespace = this.configManager.getFlag(flags.namespace) + const clusterSetupNamespace = this.configManager.getFlag(flags.clusterSetupNamespace) + + if (!deploymentNamespace && !clusterSetupNamespace) { + return null + } + const namespace = deploymentNamespace ? deploymentNamespace : clusterSetupNamespace + + if (!await this.k8.hasNamespace(namespace)) { + await this.k8.createNamespace(namespace) + + if (!await this.k8.hasNamespace(namespace)) { + throw new LeaseAcquisitionError(`failed to create the '${namespace}' namespace`) + } + } + + return namespace + } +} diff --git a/src/core/lease/lease_renewal.ts b/src/core/lease/lease_renewal.ts new file mode 100644 index 000000000..572e4dd5c --- /dev/null +++ b/src/core/lease/lease_renewal.ts @@ -0,0 +1,147 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { type Lease } from './lease.js' +import { SECONDS } from '../constants.js' + +/** + * A service for managing cancellable lease renewals. + */ +export interface LeaseRenewalService { + /** + * Determines if a lease renewal is scheduled. + * @param scheduleId - the unique identifier of the scheduled lease renewal. + * @returns true if the lease renewal is scheduled; false otherwise. + */ + isScheduled (scheduleId: number): Promise + + /** + * Schedules a lease renewal. + * @param lease - the lease to be renewed. + * @returns the unique identifier of the scheduled lease renewal. + */ + schedule (lease: Lease): Promise + + /** + * Cancels a scheduled lease renewal. + * @param scheduleId - the unique identifier of the scheduled lease renewal. + * @returns true if the lease renewal was successfully cancelled; false otherwise. + */ + cancel (scheduleId: number): Promise + + /** + * Cancels all scheduled lease renewals. + * @returns a map of the unique identifiers of the scheduled lease renewals and their cancellation status. + */ + cancelAll (): Promise> + + /** + * Calculates the delay before the next lease renewal. + * @param lease - the lease to be renewed. + * @returns the delay in milliseconds. + */ + calculateRenewalDelay (lease: Lease): number +} + +/** + * Implements a lease renewal service which utilizes a setInterval() based approach to renew leases at regular intervals. + * The renewal delay is calculated as half the duration of the lease in seconds. + */ +export class IntervalLeaseRenewalService implements LeaseRenewalService { + + /** The internal registry used to track all non-cancelled lease renewals. */ + private readonly _scheduledLeases: Map + + /** + * Constructs a new interval lease renewal service. + */ + constructor () { + this._scheduledLeases = new Map() + } + + /** + * Determines if a lease renewal is scheduled. + * This implementation uses the internal registry to track all non-cancelled lease renewals. + * + * @param scheduleId - the unique identifier of the scheduled lease renewal. + * @returns true if the lease renewal is scheduled; false otherwise. + */ + public async isScheduled (scheduleId: number): Promise { + return this._scheduledLeases.has(scheduleId) + } + + /** + * Schedules a lease renewal. + * This implementation uses the setInterval() method to renew the lease at regular intervals. + * + * @param lease - the lease to be renewed. + * @returns the unique identifier of the scheduled lease renewal. The unique identifier is the ID of the setInterval() timeout. + */ + public async schedule (lease: Lease): Promise { + const renewalDelay = this.calculateRenewalDelay(lease) + const timeout = setInterval(() => lease.tryRenew(), renewalDelay) + const scheduleId = Number(timeout) + + this._scheduledLeases.set(scheduleId, lease) + return scheduleId + } + + /** + * Cancels a scheduled lease renewal. + * This implementation uses the clearInterval() method to cancel the scheduled lease renewal. + * Due to the nature of the setInterval()/clearInterval() methods, the scheduled event may still fire at least once + * after the cancellation. + * + * @param scheduleId - the unique identifier of the scheduled lease renewal. The unique identifier is the ID of the setInterval() timeout. + * @returns true if the lease renewal was previously scheduled; false otherwise. + */ + public async cancel (scheduleId: number): Promise { + if (!scheduleId) return false + + if (this._scheduledLeases.has(scheduleId)) { + clearInterval(scheduleId) + } + + return this._scheduledLeases.delete(scheduleId) + } + + /** + * Cancels all scheduled lease renewals. + * This implementation cancels all scheduled lease renewals by iterating over the internal registry and clearing each timeout. + * @returns a map of the unique identifiers of the scheduled lease renewals and their cancellation status. + */ + public async cancelAll (): Promise> { + const result = new Map() + const keys = Array.from(this._scheduledLeases.keys()) + + for (const k of keys) { + result.set(k, await this.cancel(k)) + } + + return result + } + + /** + * Calculates the delay before the next lease renewal. + * This implementation calculates the renewal delay as half the duration of the lease. + * + * @param lease - the lease to be renewed. + * @returns the delay in milliseconds. + */ + public calculateRenewalDelay (lease: Lease): number { + return Math.round(lease.durationSeconds * 0.5) * SECONDS + } +} diff --git a/src/core/lease/listr_lease.ts b/src/core/lease/listr_lease.ts new file mode 100644 index 000000000..fa3f2c778 --- /dev/null +++ b/src/core/lease/listr_lease.ts @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { type ListrTaskWrapper } from 'listr2' +import chalk from 'chalk' +import { type Lease } from './lease.js' +import { LeaseAcquisitionError } from './lease_errors.js' + +/** + * A utility class for managing lease acquisition tasks in Listr2 based workflows. + */ +export class ListrLease { + /** + * The default number of attempts to try acquiring the lease before failing. + */ + public static readonly DEFAULT_LEASE_ACQUIRE_ATTEMPTS = 10 + + /** + * The title of the lease acquisition task used by Listr2. + */ + public static readonly ACQUIRE_LEASE_TASK_TITLE = 'Acquire lease' + + /** + * Prevents instantiation of this utility class. + */ + private constructor () { + throw new Error('This class cannot be instantiated') + } + + /** + * Creates a new Listr2 task for acquiring a lease with retry logic. + * @param lease - the lease to be acquired. + * @param task - the parent task to which the lease acquisition task will be added. + * @returns a new Listr2 task for acquiring a lease with retry logic. + */ + public static newAcquireLeaseTask (lease: Lease, task: ListrTaskWrapper) { + return task.newListr([ + { + title: ListrLease.ACQUIRE_LEASE_TASK_TITLE, + task: async (_, task) => { + await ListrLease.acquireWithRetry(lease, task) + } + } + ], { + concurrent: false, + rendererOptions: { + collapseSubtasks: false + } + }) + } + + /** + * Acquires a lease with retry logic and appropriate Listr2 status updates. This method is called by the Listr2 task + * created by the newAcquireLeaseTask() method. + * + * @param lease - the lease to be acquired. + * @param task - the task to be updated with the lease acquisition status. + * @throws LeaseAcquisitionError if the lease could not be acquired after the maximum number of attempts or an unexpected error occurred. + */ + private static async acquireWithRetry (lease: Lease, task: ListrTaskWrapper): Promise { + const maxAttempts = +process.env.SOLO_LEASE_ACQUIRE_ATTEMPTS || ListrLease.DEFAULT_LEASE_ACQUIRE_ATTEMPTS + const title = task.title + + let attempt: number + let innerError: Error | null = null + for (attempt = 0; attempt < maxAttempts; attempt++) { + try { + await lease.acquire() + task.title = `${title} - ${chalk.green('lease acquired successfully')}` + + `, attempt: ${chalk.cyan((attempt + 1).toString())}/${chalk.cyan(maxAttempts.toString())}` + return + } catch (e: LeaseAcquisitionError | any) { + task.title = `${title} - ${chalk.gray(`lease exists, attempting again in ${lease.durationSeconds} seconds`)}` + + `, attempt: ${chalk.cyan((attempt + 1).toString())}/${chalk.cyan(maxAttempts.toString())}` + + if (attempt >= maxAttempts) { + innerError = e + } + } + } + + task.title = `${title} - ${chalk.red('failed to acquire lease, max attempts reached!')}` + + `, attempt: ${chalk.cyan(attempt.toString())}/${chalk.cyan(maxAttempts.toString())}` + + throw new LeaseAcquisitionError(`Failed to acquire lease, max attempts reached (${attempt + 1}/${maxAttempts})`, innerError) + } +} diff --git a/src/core/lease_manager.ts b/src/core/lease_manager.ts deleted file mode 100644 index dafd6bb87..000000000 --- a/src/core/lease_manager.ts +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the ""License""); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an ""AS IS"" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import { MissingArgumentError, SoloError } from './errors.ts' -import { flags } from '../commands/index.ts' -import type { ConfigManager } from './config_manager.ts' -import type { K8 } from './k8.ts' -import type { SoloLogger } from './logging.ts' -import { DEFAULT_LEASE_RENEW_TIMEOUT, LEASE_ACQUIRE_RETRY_TIMEOUT, MAX_LEASE_ACQUIRE_ATTEMPTS, OS_USERNAME } from './constants.ts' -import type { ListrTaskWrapper } from 'listr2' -import chalk from 'chalk' -import { sleep } from './helpers.ts' -import { LeaseWrapper } from './lease_wrapper.ts' -import type { V1Lease } from '@kubernetes/client-node' - -export class LeaseManager { - constructor ( - private readonly k8: K8, - private readonly logger: SoloLogger, - private readonly configManager: ConfigManager - ) { - if (!k8) throw new MissingArgumentError('an instance of core/K8 is required') - if (!logger) throw new MissingArgumentError('an instance of core/SoloLogger is required') - if (!configManager) throw new MissingArgumentError('an instance of core/ConfigManager is required') - } - - instantiateLease () { - return new LeaseWrapper(this) - } - - /** - * Acquires lease if is not already taken, automatically handles renews. - * - * @returns a callback function that releases the lease - */ - async acquireLease ( - task: ListrTaskWrapper, - title: string, - attempt: number | null = null - ): Promise<{ releaseLease: () => Promise }> { - const namespace = await this.getNamespace() - - //? In case namespace isn't yet created return an empty callback function - if (!namespace) { - task.title = `${title} - ${chalk.gray('namespace not created, skipping lease acquire')}` - - return { releaseLease: async () => {} } - } - - const username = OS_USERNAME - const leaseName = `${username}-lease` - - await this.acquireLeaseOrRetry(username, leaseName, namespace, task, title, attempt) - - const renewLeaseCallback = async () => { - try { - //? Get the latest most up-to-date lease to renew it - const lease = await this.k8.readNamespacedLease(leaseName, namespace) - - await this.k8.renewNamespaceLease(leaseName, namespace, lease) - } catch (error) { - throw new SoloError(`Failed to renew lease: ${error.message}`, error) - } - } - - //? Renew lease with the callback - const renewalTimeout = +process.env.LEASE_RENEW_TIMEOUT || DEFAULT_LEASE_RENEW_TIMEOUT - const intervalId = setInterval(renewLeaseCallback, renewalTimeout) - - const releaseLeaseCallback = async () => { - //? Stop renewing the lease once release callback is called - clearInterval(intervalId) - - try { - await this.k8.deleteNamespacedLease(leaseName, namespace) - - this.logger.info(`Lease released by ${username}`) - } catch (e: Error | any) { - this.logger.error(`Failed to release lease: ${e.message}`) - } - } - - return { releaseLease: releaseLeaseCallback } - } - - private async tryAcquireLease (username: string, - leaseName: string, - namespace: string, - task: ListrTaskWrapper, - title: string): Promise { - try { - return await this.k8.readNamespacedLease(leaseName, namespace) - } catch (error) { - if (error.meta.statusCode !== 404) { - task.title = `${title} - ${chalk.red(`failed to acquire lease, unexpected server response ${error.meta.statusCode}!`)}` - } - return Promise.resolve(null) - } - } - - private async acquireLeaseOrRetry ( - username: string, - leaseName: string, - namespace: string, - task: ListrTaskWrapper, - title: string, - attempt = 1, - maxAttempts = MAX_LEASE_ACQUIRE_ATTEMPTS, - ): Promise { - if (!attempt) attempt = 1 - - let lease = await this.tryAcquireLease(username, leaseName, namespace, task, title) - - //? In case the lease is already acquired retry after cooldown - while (!!lease && !this.isLeaseExpired(lease)) { - attempt++ - - if (attempt === maxAttempts) { - task.title = `${title} - ${chalk.red('failed to acquire lease, max attempts reached!')}` + - `, attempt: ${chalk.cyan(attempt.toString())}/${chalk.cyan(maxAttempts.toString())}` - - throw new SoloError(`Failed to acquire lease, max attempt reached ${attempt}`) - } - - this.logger.info(`Lease is already taken retrying in ${LEASE_ACQUIRE_RETRY_TIMEOUT}`) - - task.title = `${title} - ${chalk.gray(`lease exists, attempting again in ${LEASE_ACQUIRE_RETRY_TIMEOUT} seconds`)}` + - `, attempt: ${chalk.cyan(attempt.toString())}/${chalk.cyan(maxAttempts.toString())}` - - await sleep(LEASE_ACQUIRE_RETRY_TIMEOUT) - lease = await this.tryAcquireLease(username, leaseName, namespace, task, title) - } - - if (lease) { - await this.k8.deleteNamespacedLease(leaseName, namespace) - } - - await this.k8.createNamespacedLease(namespace, leaseName, username) - - task.title = `${title} - ${chalk.green('lease acquired successfully')}` + - `, attempt: ${chalk.cyan(attempt.toString())}/${chalk.cyan(maxAttempts.toString())}` - } - - private async getNamespace () { - const namespace = this.configManager.getFlag(flags.namespace) - if (!namespace) return null - - if (!await this.k8.hasNamespace(namespace)) return null - return namespace - } - - private isLeaseExpired (lease: V1Lease) : boolean { - const now = Date.now() - const duration = lease.spec?.leaseDurationSeconds ? lease.spec?.leaseDurationSeconds : 20 - let acquired = lease.spec?.acquireTime - - if (lease.spec.renewTime) { - acquired = lease.spec?.renewTime - } - - const deltaSec = (now - new Date(acquired).valueOf()) / 1000 - - return deltaSec > duration - } -} diff --git a/src/core/lease_wrapper.ts b/src/core/lease_wrapper.ts deleted file mode 100644 index 641c2d44a..000000000 --- a/src/core/lease_wrapper.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the ""License""); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an ""AS IS"" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import type { ListrTaskWrapper } from 'listr2' -import type { LeaseManager } from './lease_manager.ts' - -export class LeaseWrapper { - private releaseLease: () => Promise - - constructor (private readonly leaseManager: LeaseManager) {} - - private async acquireTask (task: ListrTaskWrapper, title: string, attempt: number | null = null) { - const self = this - - const { releaseLease } = await self.leaseManager.acquireLease(task, title, attempt) - self.releaseLease = releaseLease - } - - buildAcquireTask (task: ListrTaskWrapper) { - const self = this - - return task.newListr([ - { - title: 'Acquire lease', - task: async (_, task) => { - await self.acquireTask(task, 'Acquire lease') - } - } - ], { - concurrent: false, - rendererOptions: { - collapseSubtasks: false - } - }) - } - - async release () { - if (typeof this.releaseLease === 'function') { - await this.releaseLease() - } - } -} \ No newline at end of file diff --git a/src/core/logging.ts b/src/core/logging.ts index 85aa591ac..73fe4967f 100644 --- a/src/core/logging.ts +++ b/src/core/logging.ts @@ -15,7 +15,7 @@ * */ import * as winston from 'winston' -import { constants } from './index.ts' +import { constants } from './index.js' import { v4 as uuidv4 } from 'uuid' import * as util from 'util' import chalk from 'chalk' diff --git a/src/core/network_node_services.ts b/src/core/network_node_services.ts index a9e43d1f7..8f3669543 100644 --- a/src/core/network_node_services.ts +++ b/src/core/network_node_services.ts @@ -15,7 +15,7 @@ * */ -import { type NodeAlias, type PodName } from '../types/aliases.ts' +import { type NodeAlias, type PodName } from '../types/aliases.js' export class NetworkNodeServices { public readonly nodeAlias: NodeAlias diff --git a/src/core/package_downloader.ts b/src/core/package_downloader.ts index 67c793de7..d891f78b0 100644 --- a/src/core/package_downloader.ts +++ b/src/core/package_downloader.ts @@ -25,12 +25,12 @@ import { IllegalArgumentError, MissingArgumentError, ResourceNotFoundError -} from './errors.ts' +} from './errors.js' import * as https from 'https' import * as http from 'http' -import { Templates } from './templates.ts' -import { constants } from './index.ts' -import { type SoloLogger } from './logging.ts' +import { Templates } from './templates.js' +import { constants } from './index.js' +import { type SoloLogger } from './logging.js' export class PackageDownloader { constructor (public readonly logger: SoloLogger) { diff --git a/src/core/platform_installer.ts b/src/core/platform_installer.ts index 6e660ba29..bee8bd4fc 100644 --- a/src/core/platform_installer.ts +++ b/src/core/platform_installer.ts @@ -17,15 +17,15 @@ import * as fs from 'fs' import { Listr } from 'listr2' import * as path from 'path' -import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' -import { type ConfigManager, constants, type K8 } from './index.ts' -import { Templates } from './templates.ts' -import { flags } from '../commands/index.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' +import { type ConfigManager, constants, type K8 } from './index.js' +import { Templates } from './templates.js' +import { flags } from '../commands/index.js' import * as Base64 from 'js-base64' import chalk from 'chalk' -import { type SoloLogger } from './logging.ts' -import type { NodeAlias, NodeAliases, PodName } from '../types/aliases.ts' +import { type SoloLogger } from './logging.js' +import type { NodeAlias, NodeAliases, PodName } from '../types/aliases.js' /** PlatformInstaller install platform code in the root-container of a network pod */ export class PlatformInstaller { diff --git a/src/core/process_output.ts b/src/core/process_output.ts index a8e200ace..095e25ef8 100644 --- a/src/core/process_output.ts +++ b/src/core/process_output.ts @@ -15,7 +15,7 @@ * */ import { ProcessOutput } from 'listr2' -import { type SoloLogger } from './logging.ts' +import { type SoloLogger } from './logging.js' /** Uses the solo logger to handle process output from Listr2 */ export class CustomProcessOutput extends ProcessOutput { diff --git a/src/core/profile_manager.ts b/src/core/profile_manager.ts index 271239b75..478979caf 100644 --- a/src/core/profile_manager.ts +++ b/src/core/profile_manager.ts @@ -16,18 +16,18 @@ */ import fs from 'fs' import path from 'path' -import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' import * as yaml from 'js-yaml' -import { flags } from '../commands/index.ts' -import { type ConfigManager, constants, helpers, Templates } from './index.ts' +import { flags } from '../commands/index.js' +import { type ConfigManager, constants, helpers, Templates } from './index.js' import dot from 'dot-object' -import { getNodeAccountMap } from './helpers.ts' +import { getNodeAccountMap } from './helpers.js' import * as semver from 'semver' import { readFile, writeFile } from 'fs/promises' -import { type SoloLogger } from './logging.ts' +import { type SoloLogger } from './logging.js' import { type SemVer } from 'semver' -import { type NodeAlias, type NodeAliases } from '../types/aliases.ts' +import { type NodeAlias, type NodeAliases } from '../types/aliases.js' const consensusSidecars = [ 'recordStreamUploader', 'eventStreamUploader', 'backupUploader', 'accountBalanceUploader', 'otelCollector'] diff --git a/src/core/shell_runner.ts b/src/core/shell_runner.ts index 919c978d8..28490168c 100644 --- a/src/core/shell_runner.ts +++ b/src/core/shell_runner.ts @@ -16,7 +16,7 @@ */ import { spawn } from 'child_process' import chalk from 'chalk' -import { type SoloLogger } from './logging.ts' +import { type SoloLogger } from './logging.js' export class ShellRunner { constructor (public logger: SoloLogger) { diff --git a/src/core/templates.ts b/src/core/templates.ts index 030f369c3..daf1b9c0a 100644 --- a/src/core/templates.ts +++ b/src/core/templates.ts @@ -17,11 +17,11 @@ import * as x509 from '@peculiar/x509' import os from 'os' import path from 'path' -import { DataValidationError, SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' -import { constants } from './index.ts' +import { DataValidationError, SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' +import { constants } from './index.js' import { type AccountId } from '@hashgraph/sdk' -import type { NodeAlias, PodName } from '../types/aliases.ts' -import { GrpcProxyTlsEnums } from './enumerations.ts' +import type { NodeAlias, PodName } from '../types/aliases.js' +import { GrpcProxyTlsEnums } from './enumerations.js' export class Templates { public static renderNetworkPodName (nodeAlias: NodeAlias): PodName { diff --git a/src/core/yargs_command.ts b/src/core/yargs_command.ts index 12cd7d72b..0a474e584 100644 --- a/src/core/yargs_command.ts +++ b/src/core/yargs_command.ts @@ -14,10 +14,10 @@ * limitations under the License. * */ -import * as commandFlags from '../commands/flags.ts' -import { IllegalArgumentError } from './errors.ts' -import { type BaseCommand } from '../commands/base.ts' -import { type CommandFlag } from '../types/index.ts' +import * as commandFlags from '../commands/flags.js' +import { IllegalArgumentError } from './errors.js' +import { type BaseCommand } from '../commands/base.js' +import { type CommandFlag } from '../types/index.js' export class YargsCommand { constructor ( diff --git a/src/core/zippy.ts b/src/core/zippy.ts index fc73770c9..cc1a58572 100644 --- a/src/core/zippy.ts +++ b/src/core/zippy.ts @@ -14,13 +14,13 @@ * limitations under the License. * */ -import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.ts' +import { SoloError, IllegalArgumentError, MissingArgumentError } from './errors.js' import fs from 'fs' import AdmZip from 'adm-zip' import * as tar from 'tar' import chalk from 'chalk' import path from 'path' -import type { SoloLogger } from './logging.ts' +import type { SoloLogger } from './logging.js' export class Zippy { constructor (private readonly logger: SoloLogger) { diff --git a/src/index.ts b/src/index.ts index f7cd5df92..018af247b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,18 +17,19 @@ import chalk from 'chalk' import yargs from 'yargs' import { hideBin } from 'yargs/helpers' -import { flags } from './commands/index.ts' -import * as commands from './commands/index.ts' -import { HelmDependencyManager, DependencyManager } from './core/dependency_managers/index.ts' +import { flags } from './commands/index.js' +import * as commands from './commands/index.js' +import { HelmDependencyManager, DependencyManager } from './core/dependency_managers/index.js' import { ChartManager, ConfigManager, PackageDownloader, PlatformInstaller, Helm, logging, KeyManager, Zippy, constants, ProfileManager, AccountManager, LeaseManager, CertificateManager, helpers -} from './core/index.ts' +} from './core/index.js' import 'dotenv/config' -import { K8 } from './core/k8.ts' +import { K8 } from './core/k8.js' import { ListrLogger } from 'listr2' -import { CustomProcessOutput } from './core/process_output.ts' -import { type Opts } from './types/index.ts' +import { CustomProcessOutput } from './core/process_output.js' +import { type Opts } from './types/index.js' +import { IntervalLeaseRenewalService, type LeaseRenewalService } from './core/lease/lease_renewal.js' export function main (argv: any) { const logger = logging.NewLogger('debug') @@ -57,7 +58,8 @@ export function main (argv: any) { const platformInstaller = new PlatformInstaller(logger, k8, configManager) const keyManager = new KeyManager(logger) const profileManager = new ProfileManager(logger, configManager) - const leaseManager = new LeaseManager(k8, logger, configManager) + const leaseRenewalService: LeaseRenewalService = new IntervalLeaseRenewalService() + const leaseManager = new LeaseManager(k8, configManager, logger, leaseRenewalService) const certificateManager = new CertificateManager(k8, logger, configManager) // set cluster and namespace in the global configManager from kubernetes context @@ -113,7 +115,8 @@ export function main (argv: any) { } return yargs(hideBin(argv)) - .usage('Usage:\n $0 [options]') + .scriptName('') + .usage('Usage:\n solo [options]') .alias('h', 'help') .alias('v', 'version') // @ts-ignore diff --git a/src/types/index.ts b/src/types/index.ts index 0c19d23b1..006765792 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -18,11 +18,11 @@ import type * as x509 from '@peculiar/x509' import type net from 'net' import type * as WebSocket from 'ws' import type crypto from 'crypto' -import type { SoloLogger } from '../core/logging.ts' +import type { SoloLogger } from '../core/logging.js' import type { ChartManager, ConfigManager, Helm, K8, KeyManager, PackageDownloader, PlatformInstaller, ProfileManager, DependencyManager, AccountManager, LeaseManager, CertificateManager -} from '../core/index.ts' +} from '../core/index.js' export interface NodeKeyObject { privateKey: crypto.webcrypto.CryptoKey diff --git a/test/e2e/commands/account.test.ts b/test/e2e/commands/account.test.ts index 592e8d69f..1ebd6cd7a 100644 --- a/test/e2e/commands/account.test.ts +++ b/test/e2e/commands/account.test.ts @@ -18,19 +18,19 @@ import { it, describe, after, before } from 'mocha' import { expect } from 'chai' import { AccountId, PrivateKey } from '@hashgraph/sdk' -import { constants } from '../../../src/core/index.ts' -import * as version from '../../../version.ts' +import { constants } from '../../../src/core/index.js' +import * as version from '../../../version.js' import { e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER, testLogger -} from '../../test_util.ts' -import { AccountCommand } from '../../../src/commands/account.ts' -import { flags } from '../../../src/commands/index.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import { MINUTES, SECONDS } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { AccountCommand } from '../../../src/commands/account.js' +import { flags } from '../../../src/commands/index.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import { MINUTES, SECONDS } from '../../../src/core/constants.js' const defaultTimeout = 20 * SECONDS @@ -121,7 +121,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin it('should create account with no options', async () => { try { argv[flags.amount.name] = 200 - await expect(accountCmd.create(argv)).to.eventually.be.ok + expect(await accountCmd.create(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo @@ -146,7 +146,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.amount.name] = 777 configManager.update(argv) - await expect(accountCmd.create(argv)).to.eventually.be.ok + expect(await accountCmd.create(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo @@ -168,7 +168,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.accountId.name] = accountId1 configManager.update(argv) - await expect(accountCmd.update(argv)).to.eventually.be.ok + expect(await accountCmd.update(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo @@ -190,7 +190,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.amount.name] = 333 configManager.update(argv) - await expect(accountCmd.update(argv)).to.eventually.be.ok + expect(await accountCmd.update(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo @@ -210,7 +210,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.accountId.name] = accountId1 configManager.update(argv) - await expect(accountCmd.get(argv)).to.eventually.be.ok + expect(await accountCmd.get(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo expect(accountInfo).not.to.be.null @@ -229,7 +229,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.accountId.name] = accountId2 configManager.update(argv) - await expect(accountCmd.get(argv)).to.eventually.be.ok + expect(await accountCmd.get(argv)).to.be.true // @ts-ignore to access the private property const accountInfo = accountCmd.accountInfo expect(accountInfo).not.to.be.null @@ -251,7 +251,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin argv[flags.setAlias.name] = true configManager.update(argv) - await expect(accountCmd.create(argv)).to.eventually.be.ok + expect(await accountCmd.create(argv)).to.be.true // @ts-ignore to access the private property const newAccountInfo = accountCmd.accountInfo diff --git a/test/e2e/commands/cluster.test.ts b/test/e2e/commands/cluster.test.ts index 2c1357136..f9c23fe81 100644 --- a/test/e2e/commands/cluster.test.ts +++ b/test/e2e/commands/cluster.test.ts @@ -18,12 +18,12 @@ import sinon from 'sinon' import { it, describe, after, before, afterEach, beforeEach } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' -import { bootstrapTestVariables, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER } from '../../test_util.ts' -import { constants, logging } from '../../../src/core/index.ts' -import { sleep } from '../../../src/core/helpers.ts' -import * as version from '../../../version.ts' -import { MINUTES, SECONDS } from '../../../src/core/constants.ts' +import { flags } from '../../../src/commands/index.js' +import { bootstrapTestVariables, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER } from '../../test_util.js' +import { constants, logging } from '../../../src/core/index.js' +import { sleep } from '../../../src/core/helpers.js' +import * as version from '../../../version.js' +import { MINUTES, SECONDS } from '../../../src/core/constants.js' describe('ClusterCommand', () => { // mock showUser and showJSON to silent logging during tests @@ -72,14 +72,17 @@ describe('ClusterCommand', () => { } while (!await chartManager.isChartInstalled(constants.SOLO_SETUP_NAMESPACE, constants.SOLO_CLUSTER_SETUP_CHART)) }) - beforeEach(() => configManager.reset()) + beforeEach(() => { + configManager.reset() + configManager.update(argv) + }) // give a few ticks so that connections can close afterEach(async () => await sleep(5)) it('should cleanup existing deployment', async () => { if (await chartManager.isChartInstalled(constants.SOLO_SETUP_NAMESPACE, constants.SOLO_CLUSTER_SETUP_CHART)) { - await expect(clusterCmd.reset(argv)).to.be.ok + expect(await clusterCmd.reset(argv)).to.be.true } }).timeout(MINUTES) @@ -92,7 +95,7 @@ describe('ClusterCommand', () => { it('solo cluster setup should work with valid args', async () => { argv[flags.clusterSetupNamespace.name] = namespace configManager.update(argv) - await expect(clusterCmd.setup(argv)).to.eventually.be.ok + expect(await clusterCmd.setup(argv)).to.be.true }).timeout(MINUTES) it('function getClusterInfo should return true', () => { @@ -124,6 +127,6 @@ describe('ClusterCommand', () => { it('solo cluster reset should work with valid args', async () => { argv[flags.clusterSetupNamespace.name] = namespace configManager.update(argv) - await expect(clusterCmd.reset(argv)).to.eventually.be.ok + expect(await clusterCmd.reset(argv)).to.be.true }).timeout(MINUTES) }) diff --git a/test/e2e/commands/mirror_node.test.ts b/test/e2e/commands/mirror_node.test.ts index 6dc75842b..b8cc383f6 100644 --- a/test/e2e/commands/mirror_node.test.ts +++ b/test/e2e/commands/mirror_node.test.ts @@ -17,7 +17,7 @@ import { it, describe, after, before, afterEach } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, @@ -25,15 +25,15 @@ import { getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER -} from '../../test_util.ts' -import * as version from '../../../version.ts' -import { getNodeLogs, sleep } from '../../../src/core/helpers.ts' -import { MirrorNodeCommand } from '../../../src/commands/mirror_node.ts' -import * as core from '../../../src/core/index.ts' +} from '../../test_util.js' +import * as version from '../../../version.js' +import { getNodeLogs, sleep } from '../../../src/core/helpers.js' +import { MirrorNodeCommand } from '../../../src/commands/mirror_node.js' +import * as core from '../../../src/core/index.js' import { Status, TopicCreateTransaction, TopicMessageSubmitTransaction } from '@hashgraph/sdk' import * as http from 'http' -import { MINUTES, SECONDS } from '../../../src/core/constants.ts' -import type { PodName } from '../../../src/types/aliases.ts' +import { MINUTES, SECONDS } from '../../../src/core/constants.js' +import type { PodName } from '../../../src/types/aliases.js' const testName = 'mirror-cmd-e2e' const namespace = testName @@ -84,7 +84,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin it('mirror node deploy should success', async () => { try { - await expect(mirrorNodeCmd.deploy(argv)).to.eventually.be.ok + expect(await mirrorNodeCmd.deploy(argv)).to.be.true } catch (e) { mirrorNodeCmd.logger.showUserError(e) expect.fail() @@ -113,7 +113,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin // check if mirror node api server is running const apiURL = 'http://127.0.0.1:8080/api/v1/transactions' - await expect(downloader.urlExists(apiURL)).to.eventually.be.ok + expect(await downloader.urlExists(apiURL)).to.be.true await sleep(2 * SECONDS) } catch (e) { mirrorNodeCmd.logger.showUserError(e) @@ -124,7 +124,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin it('Explorer GUI should be running', async () => { try { const guiURL = 'http://127.0.0.1:8080/localnet/dashboard' - await expect(downloader.urlExists(guiURL)).to.eventually.be.ok + expect(await downloader.urlExists(guiURL)).to.be.true await sleep(2 * SECONDS) mirrorNodeCmd.logger.debug('mirror node API and explorer GUI are running') @@ -203,7 +203,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin it('mirror node destroy should success', async () => { try { - await expect(mirrorNodeCmd.destroy(argv)).to.eventually.be.ok + expect(await mirrorNodeCmd.destroy(argv)).to.be.true } catch (e) { mirrorNodeCmd.logger.showUserError(e) expect.fail() diff --git a/test/e2e/commands/network.test.ts b/test/e2e/commands/network.test.ts index 741a136aa..def94b33e 100644 --- a/test/e2e/commands/network.test.ts +++ b/test/e2e/commands/network.test.ts @@ -22,15 +22,15 @@ import { getDefaultArgv, getTmpDir, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { constants } from '../../../src/core/index.ts' -import * as version from '../../../version.ts' -import { getNodeLogs, sleep } from '../../../src/core/helpers.ts' +} from '../../test_util.js' +import { constants } from '../../../src/core/index.js' +import * as version from '../../../version.js' +import { getNodeLogs, sleep } from '../../../src/core/helpers.js' import path from 'path' import fs from 'fs' -import { NetworkCommand } from '../../../src/commands/network.ts' -import { MINUTES, SECONDS } from '../../../src/core/constants.ts' -import { flags } from '../../../src/commands/index.ts' +import { NetworkCommand } from '../../../src/commands/network.js' +import { MINUTES, SECONDS } from '../../../src/core/constants.js' +import { flags } from '../../../src/commands/index.js' describe('NetworkCommand', () => { const testName = 'network-cmd-e2e' @@ -78,12 +78,12 @@ describe('NetworkCommand', () => { }) it('keys should be generated', async () => { - await expect(nodeCmd.handlers.keys(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.keys(argv)).to.be.true }) it('network deploy command should succeed', async () => { try { - await expect(networkCmd.deploy(argv)).to.eventually.be.ok + expect(await networkCmd.deploy(argv)).to.be.true // check pod names should match expected values await expect(k8.getPodByName('network-node1-0')) @@ -129,7 +129,8 @@ describe('NetworkCommand', () => { configManager.update(argv) try { - await expect(networkCmd.destroy(argv)).to.eventually.be.ok + const destroyResult = await networkCmd.destroy(argv) + expect(destroyResult).to.be.true while ((await k8.getPodsByLabel(['solo.hedera.com/type=network-node'])).length > 0) { networkCmd.logger.debug('Pods are still running. Waiting...') @@ -142,8 +143,8 @@ describe('NetworkCommand', () => { } // check if chart is uninstalled - await expect(bootstrapResp.opts.chartManager.isChartInstalled(namespace, constants.SOLO_DEPLOYMENT_CHART)) - .to.eventually.not.be.ok + const chartInstalledStatus = await bootstrapResp.opts.chartManager.isChartInstalled(namespace, constants.SOLO_DEPLOYMENT_CHART) + expect(chartInstalledStatus).to.be.false // check if pvc are deleted await expect(k8.listPvcsByNamespace(namespace)).eventually.to.have.lengthOf(0) diff --git a/test/e2e/commands/node_add.test.ts b/test/e2e/commands/node_add.test.ts index 2950f3351..c401777f7 100644 --- a/test/e2e/commands/node_add.test.ts +++ b/test/e2e/commands/node_add.test.ts @@ -14,8 +14,8 @@ * limitations under the License. * */ -import { testNodeAdd } from '../../test_add.ts' -import { MINUTES } from '../../../src/core/constants.ts' +import { testNodeAdd } from '../../test_add.js' +import { MINUTES } from '../../../src/core/constants.js' const localBuildPath = '' testNodeAdd(localBuildPath, 'Node add with released hedera', 3 * MINUTES) diff --git a/test/e2e/commands/node_add_local.test.ts b/test/e2e/commands/node_add_local.test.ts index 96afcc79e..5aed64505 100644 --- a/test/e2e/commands/node_add_local.test.ts +++ b/test/e2e/commands/node_add_local.test.ts @@ -16,8 +16,8 @@ */ import { describe } from 'mocha' -import { testNodeAdd } from '../../test_add.ts' -import { MINUTES } from '../../../src/core/constants.ts' +import { testNodeAdd } from '../../test_add.js' +import { MINUTES } from '../../../src/core/constants.js' describe('Node add with hedera local build', () => { const localBuildPath = 'node1=../hedera-services/hedera-node/data/,../hedera-services/hedera-node/data,node3=../hedera-services/hedera-node/data' diff --git a/test/e2e/commands/node_delete.test.ts b/test/e2e/commands/node_delete.test.ts index c6ccb262f..dc421635a 100644 --- a/test/e2e/commands/node_delete.test.ts +++ b/test/e2e/commands/node_delete.test.ts @@ -17,19 +17,19 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs, getTmpDir } from '../../../src/core/helpers.ts' -import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { getNodeLogs, getTmpDir } from '../../../src/core/helpers.js' +import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.js' import fs from 'fs' -import type { PodName } from '../../../src/types/aliases.ts' -import * as NodeCommandConfigs from '../../../src/commands/node/configs.ts' +import type { PodName } from '../../../src/types/aliases.js' +import * as NodeCommandConfigs from '../../../src/commands/node/configs.js' const namespace = 'node-delete' const nodeAlias = 'node1' diff --git a/test/e2e/commands/node_local_hedera.test.ts b/test/e2e/commands/node_local_hedera.test.ts index 8fe9f3176..a5782491a 100644 --- a/test/e2e/commands/node_local_hedera.test.ts +++ b/test/e2e/commands/node_local_hedera.test.ts @@ -16,15 +16,15 @@ */ import { describe } from 'mocha' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER -} from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import { MINUTES } from '../../../src/core/constants.ts' -import type { K8 } from '../../../src/core/index.ts' +} from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import { MINUTES } from '../../../src/core/constants.js' +import type { K8 } from '../../../src/core/index.js' const LOCAL_HEDERA = 'local-hedera-app' const argv = getDefaultArgv() diff --git a/test/e2e/commands/node_local_ptt.test.ts b/test/e2e/commands/node_local_ptt.test.ts index f5a15c574..514eaee02 100644 --- a/test/e2e/commands/node_local_ptt.test.ts +++ b/test/e2e/commands/node_local_ptt.test.ts @@ -16,10 +16,10 @@ */ import { describe, } from 'mocha' -import { flags } from '../../../src/commands/index.ts' -import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER } from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import { MINUTES } from '../../../src/core/constants.ts' +import { flags } from '../../../src/commands/index.js' +import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER } from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import { MINUTES } from '../../../src/core/constants.js' const LOCAL_PTT = 'local-ptt-app' const argv = getDefaultArgv() diff --git a/test/e2e/commands/node_pem_kill.test.ts b/test/e2e/commands/node_pem_kill.test.ts index 2a1374f2f..d0638d596 100644 --- a/test/e2e/commands/node_pem_kill.test.ts +++ b/test/e2e/commands/node_pem_kill.test.ts @@ -14,6 +14,6 @@ * limitations under the License. * */ -import { e2eNodeKeyRefreshTest } from '../e2e_node_util.ts' +import { e2eNodeKeyRefreshTest } from '../e2e_node_util.js' e2eNodeKeyRefreshTest('node-cmd-e2e-pem-kill', 'kill') diff --git a/test/e2e/commands/node_pem_stop.test.ts b/test/e2e/commands/node_pem_stop.test.ts index b09d9e08c..bb81fcd6b 100644 --- a/test/e2e/commands/node_pem_stop.test.ts +++ b/test/e2e/commands/node_pem_stop.test.ts @@ -14,6 +14,6 @@ * limitations under the License. * */ -import { e2eNodeKeyRefreshTest } from '../e2e_node_util.ts' +import { e2eNodeKeyRefreshTest } from '../e2e_node_util.js' e2eNodeKeyRefreshTest('node-cmd-e2e-pem-stop', 'stop') diff --git a/test/e2e/commands/node_update.test.ts b/test/e2e/commands/node_update.test.ts index 482873fab..9b0ac6b2d 100644 --- a/test/e2e/commands/node_update.test.ts +++ b/test/e2e/commands/node_update.test.ts @@ -17,20 +17,20 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' -import { constants } from '../../../src/core/index.ts' +import { flags } from '../../../src/commands/index.js' +import { constants } from '../../../src/core/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, e2eTestSuite, getDefaultArgv, getNodeAliasesPrivateKeysHash, getTmpDir, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.js' import fs from 'fs' -import type { PodName } from '../../../src/types/aliases.ts' -import * as NodeCommandConfigs from '../../../src/commands/node/configs.ts' +import type { PodName } from '../../../src/types/aliases.js' +import * as NodeCommandConfigs from '../../../src/commands/node/configs.js' const defaultTimeout = 2 * MINUTES const namespace = 'node-update' diff --git a/test/e2e/commands/node_upgrade.test.ts b/test/e2e/commands/node_upgrade.test.ts index ceaf581fa..225bde4ba 100644 --- a/test/e2e/commands/node_upgrade.test.ts +++ b/test/e2e/commands/node_upgrade.test.ts @@ -17,18 +17,18 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' +} from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' import { PREPARE_UPGRADE_CONFIGS_NAME, DOWNLOAD_GENERATED_FILES_CONFIGS_NAME -} from '../../../src/commands/node/configs.ts' -import { MINUTES } from '../../../src/core/constants.ts' +} from '../../../src/commands/node/configs.js' +import { MINUTES } from '../../../src/core/constants.js' const namespace = 'node-upgrade' const argv = getDefaultArgv() diff --git a/test/e2e/commands/relay.test.ts b/test/e2e/commands/relay.test.ts index e73536a58..60979e912 100644 --- a/test/e2e/commands/relay.test.ts +++ b/test/e2e/commands/relay.test.ts @@ -18,12 +18,12 @@ import { after, afterEach, describe } from 'mocha' import { expect } from 'chai' import each from 'mocha-each' -import { flags } from '../../../src/commands/index.ts' -import { e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER } from '../../test_util.ts' -import * as version from '../../../version.ts' -import { getNodeLogs, sleep } from '../../../src/core/helpers.ts' -import { RelayCommand } from '../../../src/commands/relay.ts' -import { MINUTES } from '../../../src/core/constants.ts' +import { flags } from '../../../src/commands/index.js' +import { e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER } from '../../test_util.js' +import * as version from '../../../version.js' +import { getNodeLogs, sleep } from '../../../src/core/helpers.js' +import { RelayCommand } from '../../../src/commands/relay.js' +import { MINUTES } from '../../../src/core/constants.js' const testName = 'relay-cmd-e2e' const namespace = testName @@ -61,7 +61,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin // test relay deploy try { - await expect(relayCmd.deploy(argv)).to.eventually.be.ok + expect(await relayCmd.deploy(argv)).to.be.true } catch (e) { relayCmd.logger.showUserError(e) expect.fail() @@ -75,7 +75,7 @@ e2eTestSuite(testName, argv, undefined, undefined, undefined, undefined, undefin // test relay destroy try { - await expect(relayCmd.destroy(argv)).to.eventually.be.ok + expect(await relayCmd.destroy(argv)).to.be.true } catch (e) { relayCmd.logger.showUserError(e) expect.fail() diff --git a/test/e2e/commands/separate_node_add.test.ts b/test/e2e/commands/separate_node_add.test.ts index 977778b60..5ec1e5ef0 100644 --- a/test/e2e/commands/separate_node_add.test.ts +++ b/test/e2e/commands/separate_node_add.test.ts @@ -17,7 +17,7 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, @@ -25,10 +25,10 @@ import { getDefaultArgv, getNodeAliasesPrivateKeysHash, getTmpDir, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import * as NodeCommandConfigs from '../../../src/commands/node/configs.ts' -import { MINUTES } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import * as NodeCommandConfigs from '../../../src/commands/node/configs.js' +import { MINUTES } from '../../../src/core/constants.js' const defaultTimeout = 2 * MINUTES const namespace = 'node-add-separated' diff --git a/test/e2e/commands/separate_node_delete.test.ts b/test/e2e/commands/separate_node_delete.test.ts index e5e182473..b45a80ff9 100644 --- a/test/e2e/commands/separate_node_delete.test.ts +++ b/test/e2e/commands/separate_node_delete.test.ts @@ -17,19 +17,19 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, e2eTestSuite, getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs, getTmpDir } from '../../../src/core/helpers.ts' -import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { getNodeLogs, getTmpDir } from '../../../src/core/helpers.js' +import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.js' import fs from 'fs' -import type { NodeAlias, PodName } from '../../../src/types/aliases.ts' -import * as NodeCommandConfigs from '../../../src/commands/node/configs.ts' +import type { NodeAlias, PodName } from '../../../src/types/aliases.js' +import * as NodeCommandConfigs from '../../../src/commands/node/configs.js' const namespace = 'node-delete-separate' const nodeAlias = 'node1' as NodeAlias diff --git a/test/e2e/commands/separate_node_update.test.ts b/test/e2e/commands/separate_node_update.test.ts index 23bba32d1..1aec0bfa7 100644 --- a/test/e2e/commands/separate_node_update.test.ts +++ b/test/e2e/commands/separate_node_update.test.ts @@ -17,20 +17,20 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../src/commands/index.ts' -import { constants } from '../../../src/core/index.ts' +import { flags } from '../../../src/commands/index.js' +import { constants } from '../../../src/core/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, e2eTestSuite, getDefaultArgv, getNodeAliasesPrivateKeysHash, getTmpDir, HEDERA_PLATFORM_VERSION_TAG -} from '../../test_util.ts' -import { getNodeLogs } from '../../../src/core/helpers.ts' -import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.ts' +} from '../../test_util.js' +import { getNodeLogs } from '../../../src/core/helpers.js' +import { HEDERA_HAPI_PATH, MINUTES, ROOT_CONTAINER } from '../../../src/core/constants.js' import fs from 'fs' -import type { PodName } from '../../../src/types/aliases.ts' -import * as NodeCommandConfigs from '../../../src/commands/node/configs.ts' +import type { PodName } from '../../../src/types/aliases.js' +import * as NodeCommandConfigs from '../../../src/commands/node/configs.js' const defaultTimeout = 2 * MINUTES const namespace = 'node-update-separate' diff --git a/test/e2e/e2e_node_util.ts b/test/e2e/e2e_node_util.ts index e1fad71b8..bfbe2d1cc 100644 --- a/test/e2e/e2e_node_util.ts +++ b/test/e2e/e2e_node_util.ts @@ -17,7 +17,7 @@ import { it, describe, after, before, afterEach } from 'mocha' import { expect } from 'chai' -import { flags } from '../../src/commands/index.ts' +import { flags } from '../../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, @@ -25,14 +25,14 @@ import { getDefaultArgv, HEDERA_PLATFORM_VERSION_TAG, TEST_CLUSTER, testLogger -} from '../test_util.ts' -import { getNodeLogs, sleep } from '../../src/core/helpers.ts' -import * as NodeCommandConfigs from '../../src/commands/node/configs.ts' -import { MINUTES, SECONDS } from '../../src/core/constants.ts' -import type { NodeAlias } from '../../src/types/aliases.ts' +} from '../test_util.js' +import { getNodeLogs, sleep } from '../../src/core/helpers.js' +import * as NodeCommandConfigs from '../../src/commands/node/configs.js' +import { MINUTES, SECONDS } from '../../src/core/constants.js' +import type { NodeAlias } from '../../src/types/aliases.js' import type { ListrTaskWrapper } from 'listr2' -import { ConfigManager, type K8 } from '../../src/core/index.ts' -import { type NodeCommand } from '../../src/commands/node/index.ts' +import { ConfigManager, type K8 } from '../../src/core/index.js' +import { type NodeCommand } from '../../src/commands/node/index.js' export function e2eNodeKeyRefreshTest (testName: string, mode: string, releaseTag = HEDERA_PLATFORM_VERSION_TAG) { const namespace = testName @@ -77,10 +77,11 @@ export function e2eNodeKeyRefreshTest (testName: string, mode: string, releaseTa it(`Node Proxy should be UP [mode ${mode}, release ${releaseTag}`, async () => { try { - await expect(k8.waitForPodReady( - ['app=haproxy-node1', - 'solo.hedera.com/type=haproxy'], - 1, 300, 1000)).to.eventually.be.ok + const labels = ['app=haproxy-node1', 'solo.hedera.com/type=haproxy'] + const readyPods = await k8.waitForPodReady(labels, 1, 300, 1000) + expect(readyPods).to.not.be.null + expect(readyPods).to.not.be.undefined + expect(readyPods.length).to.be.greaterThan(0) } catch (e) { nodeCmd.logger.showUserError(e) expect.fail() @@ -103,7 +104,7 @@ export function e2eNodeKeyRefreshTest (testName: string, mode: string, releaseTa expect(resp.response.statusCode).to.equal(200) await sleep(20 * SECONDS) // sleep to wait for pod to finish terminating } else if (mode === 'stop') { - await expect(nodeCmd.handlers.stop(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.stop(argv)).to.be.true await sleep(20 * SECONDS) // give time for node to stop and update its logs } else { throw new Error(`invalid mode: ${mode}`) @@ -125,8 +126,8 @@ export function e2eNodeKeyRefreshTest (testName: string, mode: string, releaseTa it(`${nodeAlias} should be running`, async () => { try { // @ts-ignore to access tasks which is a private property - await expect(nodeCmd.tasks.checkNetworkNodePod(namespace, - nodeAlias)).to.eventually.be.ok + expect(await nodeCmd.tasks.checkNetworkNodePod(namespace, + nodeAlias)).to.equal(`network-${nodeAlias}-0`) } catch (e) { nodeCmd.logger.showUserError(e) expect.fail() @@ -139,7 +140,7 @@ export function e2eNodeKeyRefreshTest (testName: string, mode: string, releaseTa function nodeRefreshShouldSucceed (nodeAlias: NodeAlias, nodeCmd: NodeCommand, argv: Record) { it(`${nodeAlias} refresh should succeed`, async () => { try { - await expect(nodeCmd.handlers.refresh(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.refresh(argv)).to.be.true expect(nodeCmd.getUnusedConfigs( NodeCommandConfigs.REFRESH_CONFIGS_NAME)).to.deep.equal([ flags.devMode.constName, diff --git a/test/e2e/integration/commands/init.test.ts b/test/e2e/integration/commands/init.test.ts index f6f8002d6..ae5b316f4 100644 --- a/test/e2e/integration/commands/init.test.ts +++ b/test/e2e/integration/commands/init.test.ts @@ -17,16 +17,17 @@ import { describe, it } from 'mocha' import { expect } from 'chai' -import { InitCommand } from '../../../../src/commands/init.ts' +import { InitCommand } from '../../../../src/commands/init.js' import { HelmDependencyManager, DependencyManager -} from '../../../../src/core/dependency_managers/index.ts' +} from '../../../../src/core/dependency_managers/index.js' import { ChartManager, ConfigManager, constants, Helm, K8, KeyManager, LeaseManager, logging, PackageDownloader, Zippy -} from '../../../../src/core/index.ts' -import { SECONDS } from '../../../../src/core/constants.ts' +} from '../../../../src/core/index.js' +import { SECONDS } from '../../../../src/core/constants.js' import sinon from 'sinon' +import { IntervalLeaseRenewalService } from '../../../../src/core/lease/lease_renewal.js' const testLogger = logging.NewLogger('debug', true) describe('InitCommand', () => { @@ -54,7 +55,7 @@ describe('InitCommand', () => { sandbox = sinon.createSandbox() sandbox.stub(K8.prototype, 'init').callsFake(() => this) k8 = new K8(configManager, testLogger) - leaseManager = new LeaseManager(k8, testLogger, configManager) + leaseManager = new LeaseManager(k8, configManager, testLogger, new IntervalLeaseRenewalService()) // @ts-ignore initCmd = new InitCommand({ logger: testLogger, helm, k8, chartManager, configManager, depManager, keyManager, leaseManager diff --git a/test/e2e/integration/core/account_manager.test.ts b/test/e2e/integration/core/account_manager.test.ts index 0828f2758..928c8a89a 100644 --- a/test/e2e/integration/core/account_manager.test.ts +++ b/test/e2e/integration/core/account_manager.test.ts @@ -17,11 +17,11 @@ import { it, describe, after } from 'mocha' import { expect } from 'chai' -import { flags } from '../../../../src/commands/index.ts' -import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER } from '../../../test_util.ts' -import * as version from '../../../../version.ts' -import { MINUTES } from '../../../../src/core/constants.ts' -import type { PodName } from '../../../../src/types/aliases.ts' +import { flags } from '../../../../src/commands/index.js' +import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER } from '../../../test_util.js' +import * as version from '../../../../version.js' +import { MINUTES } from '../../../../src/core/constants.js' +import type { PodName } from '../../../../src/types/aliases.js' const namespace = 'account-mngr-e2e' const argv = getDefaultArgv() diff --git a/test/e2e/integration/core/chart_manager.test.ts b/test/e2e/integration/core/chart_manager.test.ts index 2a69641e0..f4f1a6286 100644 --- a/test/e2e/integration/core/chart_manager.test.ts +++ b/test/e2e/integration/core/chart_manager.test.ts @@ -17,8 +17,8 @@ import { it, describe } from 'mocha' import { expect } from 'chai' -import { ChartManager, Helm, constants } from '../../../../src/core/index.ts' -import { testLogger } from '../../../test_util.ts' +import { ChartManager, Helm, constants } from '../../../../src/core/index.js' +import { testLogger } from '../../../test_util.js' describe('ChartManager', () => { const helm = new Helm(testLogger) diff --git a/test/e2e/integration/core/dependency_managers/helm_dependency_manager.test.ts b/test/e2e/integration/core/dependency_managers/helm_dependency_manager.test.ts index 9ef67ec5c..b7808cd5c 100644 --- a/test/e2e/integration/core/dependency_managers/helm_dependency_manager.test.ts +++ b/test/e2e/integration/core/dependency_managers/helm_dependency_manager.test.ts @@ -20,10 +20,10 @@ import each from 'mocha-each' import fs from 'fs' import path from 'path' -import { HelmDependencyManager } from '../../../../../src/core/dependency_managers/index.ts' -import { PackageDownloader, Zippy } from '../../../../../src/core/index.ts' -import { getTestCacheDir, getTmpDir, testLogger } from '../../../../test_util.ts' -import * as version from '../../../../../version.ts' +import { HelmDependencyManager } from '../../../../../src/core/dependency_managers/index.js' +import { PackageDownloader, Zippy } from '../../../../../src/core/index.js' +import { getTestCacheDir, getTmpDir, testLogger } from '../../../../test_util.js' +import * as version from '../../../../../version.js' describe('HelmDependencyManager', () => { const downloader = new PackageDownloader(testLogger) @@ -71,7 +71,7 @@ describe('HelmDependencyManager', () => { helmDependencyManager.uninstall() expect(helmDependencyManager.isInstalled()).not.to.be.ok - await expect(helmDependencyManager.install(getTestCacheDir())).to.eventually.be.ok + expect(await helmDependencyManager.install(getTestCacheDir())).to.be.true expect(helmDependencyManager.isInstalled()).to.be.ok fs.rmSync(tmpDir, { recursive: true }) diff --git a/test/e2e/integration/core/k8_e2e.test.ts b/test/e2e/integration/core/k8_e2e.test.ts index 243bc8716..8b4dd5090 100644 --- a/test/e2e/integration/core/k8_e2e.test.ts +++ b/test/e2e/integration/core/k8_e2e.test.ts @@ -23,10 +23,10 @@ import net from 'net' import os from 'os' import path from 'path' import { v4 as uuid4 } from 'uuid' -import { SoloError } from '../../../../src/core/errors.ts' -import { ConfigManager, constants, logging, Templates } from '../../../../src/core/index.ts' -import { K8 } from '../../../../src/core/k8.ts' -import { flags } from '../../../../src/commands/index.ts' +import { SoloError } from '../../../../src/core/errors.js' +import { ConfigManager, constants, logging, Templates } from '../../../../src/core/index.js' +import { K8 } from '../../../../src/core/k8.js' +import { flags } from '../../../../src/commands/index.js' import { V1Container, V1ExecAction, @@ -42,8 +42,8 @@ import { V1VolumeResourceRequirements } from '@kubernetes/client-node' import crypto from 'crypto' -import { MINUTES } from '../../../../src/core/constants.ts' -import type { PodName } from '../../../../src/types/aliases.ts' +import { MINUTES } from '../../../../src/core/constants.js' +import type { PodName } from '../../../../src/types/aliases.js' const defaultTimeout = 2 * MINUTES @@ -134,8 +134,8 @@ describe('K8', () => { it('should be able to create and delete a namespaces', async () => { const name = uuid4() - await expect(k8.createNamespace(name)).to.eventually.be.ok - await expect(k8.deleteNamespace(name)).to.eventually.be.ok + expect(await k8.createNamespace(name)).to.be.true + expect(await k8.deleteNamespace(name)).to.be.true }).timeout(defaultTimeout) it('should be able to run wait for pod', async () => { @@ -178,7 +178,7 @@ describe('K8', () => { it('should be able to check if a path is directory inside a container', async () => { const pods = await k8.getPodsByLabel([`app=${podLabelValue}`]) const podName = pods[0].metadata.name - await expect(k8.hasDir(podName, containerName, '/tmp')).to.eventually.be.ok + expect(await k8.hasDir(podName, containerName, '/tmp')).to.be.true }).timeout(defaultTimeout) const testCases = [ 'test/data/pem/keys/a-private-node0.pem', 'test/data/build-v0.54.0-alpha.4.zip' ] @@ -197,10 +197,10 @@ describe('K8', () => { const originalStat = fs.statSync(localFilePath) // upload the file - await expect(k8.copyTo(podName, containerName, localFilePath, remoteTmpDir)).to.eventually.be.ok + expect(await k8.copyTo(podName, containerName, localFilePath, remoteTmpDir)).to.be.true // download the same file - await expect(k8.copyFrom(podName, containerName, remoteFilePath, localTmpDir)).to.eventually.be.ok + expect(await k8.copyFrom(podName, containerName, remoteFilePath, localTmpDir)).to.be.true const downloadedFilePath = path.join(localTmpDir, fileName) const downloadedFileData = fs.readFileSync(downloadedFilePath) const downloadedFileHash = crypto.createHash('sha384').update(downloadedFileData).digest('hex') diff --git a/test/e2e/integration/core/lease.test.ts b/test/e2e/integration/core/lease.test.ts new file mode 100644 index 000000000..37498c89f --- /dev/null +++ b/test/e2e/integration/core/lease.test.ts @@ -0,0 +1,182 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { it, describe, before, after } from 'mocha' +import { ConfigManager, logging } from '../../../../src/core/index.js' +import { K8 } from '../../../../src/core/k8.js' +import { MINUTES, SECONDS } from '../../../../src/core/constants.js' +import { expect } from 'chai' +import { Lease } from '../../../../src/core/lease/lease.js' +import { LeaseHolder } from '../../../../src/core/lease/lease_holder.js' +import { sleep } from '../../../../src/core/helpers.js' +import { LeaseRelinquishmentError } from '../../../../src/core/lease/lease_errors.js' +import { NoopLeaseRenewalService } from './noop_lease_renewal_service.test.js' + + +const defaultTimeout = 2 * MINUTES +const leaseDuration = 4 + +describe('Lease', async function () { + const testLogger = logging.NewLogger('debug', true) + const configManager = new ConfigManager(testLogger) + const k8 = new K8(configManager, testLogger) + const testNamespace = 'lease-e2e' + const renewalService = new NoopLeaseRenewalService() + + before(async function () { + this.timeout(defaultTimeout) + if (await k8.hasNamespace(testNamespace)) { + await k8.deleteNamespace(testNamespace) + await sleep(5 * SECONDS) + } + + await k8.createNamespace(testNamespace) + }) + + after(async function () { + this.timeout(defaultTimeout) + await k8.deleteNamespace(testNamespace) + }) + + describe('acquire and release', async function () { + this.timeout(defaultTimeout) + + it('non-expired lease', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + + await lease.acquire() + expect(await lease.isAcquired()).to.be.true + + await lease.release() + expect(await lease.isAcquired()).to.be.false + }) + + it('non-expired lease held by another user should not be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + const newLease = new Lease(k8, renewalService, LeaseHolder.of('other'), testNamespace, null, leaseDuration) + + await lease.acquire() + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + expect(newLease.release()).to.be.rejectedWith(LeaseRelinquishmentError) + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + await lease.release() + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + + it('expired lease held by another user should be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + const newLease = new Lease(k8, renewalService, LeaseHolder.of('other'), testNamespace, null, leaseDuration) + + await lease.acquire() + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + await sleep(lease.durationSeconds * SECONDS) + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.true + + await newLease.release() + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + + it('expired lease should be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + + await lease.acquire() + expect(await lease.isAcquired()).to.be.true + + await sleep(lease.durationSeconds * SECONDS) + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.true + + await lease.release() + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + }) + + describe('tryAcquire and tryRelease', async function () { + this.timeout(defaultTimeout) + + it('non-expired lease', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + + expect(await lease.tryAcquire()).to.be.true + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + expect(await lease.tryRelease()).to.be.true + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + + it('non-expired lease held by another user should not be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + const newLease = new Lease(k8, renewalService, LeaseHolder.of('other'), testNamespace, null, leaseDuration) + + expect(await lease.tryAcquire()).to.be.true + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + expect(await newLease.tryRelease()).to.be.false + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + expect(await lease.tryRelease()).to.be.true + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + + it('expired lease held by another user should be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + const newLease = new Lease(k8, renewalService, LeaseHolder.of('other'), testNamespace, null, leaseDuration) + + expect(await lease.tryAcquire()).to.be.true + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + await sleep(lease.durationSeconds * SECONDS) + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.true + + expect(await newLease.tryRelease()).to.be.true + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + + it('expired lease should be released', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + + expect(await lease.tryAcquire()).to.be.true + expect(await lease.isAcquired()).to.be.true + expect(await lease.isExpired()).to.be.false + + await sleep(lease.durationSeconds * SECONDS) + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.true + + expect(await lease.tryRelease()).to.be.true + expect(await lease.isAcquired()).to.be.false + expect(await lease.isExpired()).to.be.false + }) + }) +}) diff --git a/test/e2e/integration/core/lease_manager.test.ts b/test/e2e/integration/core/lease_manager.test.ts deleted file mode 100644 index 8148ebd03..000000000 --- a/test/e2e/integration/core/lease_manager.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the ""License""); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an ""AS IS"" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import { it, describe, after } from 'mocha' -import { expect } from 'chai' - -import { flags } from '../../../../src/commands/index.ts' -import { e2eTestSuite, getDefaultArgv, TEST_CLUSTER } from '../../../test_util.ts' -import * as version from '../../../../version.ts' -import { - DEFAULT_LEASE_RENEW_TIMEOUT, - LEASE_ACQUIRE_RETRY_TIMEOUT, - MAX_LEASE_ACQUIRE_ATTEMPTS, - MINUTES -} from '../../../../src/core/constants.ts' -import { sleep } from '../../../../src/core/helpers.js' - -const namespace = 'lease-mngr-e2e' -const argv = getDefaultArgv() -argv[flags.namespace.name] = namespace -argv[flags.nodeAliasesUnparsed.name] = 'node1' -argv[flags.clusterName.name] = TEST_CLUSTER -argv[flags.soloChartVersion.name] = version.SOLO_CHART_VERSION -argv[flags.generateGossipKeys.name] = true -argv[flags.generateTlsKeys.name] = true -// set the env variable SOLO_CHARTS_DIR if developer wants to use local Solo charts -argv[flags.chartDirectory.name] = process.env.SOLO_CHARTS_DIR ?? undefined - -e2eTestSuite(namespace, argv, undefined, undefined, undefined, undefined, undefined, undefined, false, (bootstrapResp) => { - describe('LeaseManager', async () => { - const k8 = bootstrapResp.opts.k8 - const leaseManager = bootstrapResp.opts.leaseManager - - after(async function () { - this.timeout(2 * MINUTES) - - await k8.deleteNamespace(namespace) - }) - - it('should be able to create lease and release it', async () => { - const lease = leaseManager.instantiateLease() - const title = 'Testing title' - // @ts-ignore to access private property - await lease.acquireTask({ title }, title) - - expect(typeof lease.release).to.equal('function') - await lease.release() - }) - - it('should not be able to create second lease in the same namespace', async () => { - // Create first lease - const initialLease = leaseManager.instantiateLease() - const title = 'Testing title' - // @ts-ignore to access private property - await initialLease.acquireTask({ title }, title) - - const blockedLease = leaseManager.instantiateLease() - - try { - // @ts-ignore to access private property - await blockedLease.acquireTask({ title }, title, MAX_LEASE_ACQUIRE_ATTEMPTS - 1) - - await sleep(LEASE_ACQUIRE_RETRY_TIMEOUT * 2) - } catch (e: Error | any) { - expect(e.message).to.contain('Failed to acquire lease, max attempt reached') - } - - await initialLease.release() - }).timeout(3 * MINUTES) - - it('expired leases should be overwritten', async () => { - process.env.LEASE_RENEW_TIMEOUT = (DEFAULT_LEASE_RENEW_TIMEOUT * 4).toString() - const initialLease = leaseManager.instantiateLease() - const title = 'Initial Lease' - // @ts-ignore to access private property - await initialLease.acquireTask({ title }, title) - - // Ensure lease expires - await sleep(LEASE_ACQUIRE_RETRY_TIMEOUT) - - process.env.LEASE_RENEW_TIMEOUT = DEFAULT_LEASE_RENEW_TIMEOUT.toString() - const newLease = leaseManager.instantiateLease() - const newTitle = 'New Lease' - // @ts-ignore to access private property - await newLease.acquireTask({ newTitle }, newTitle, 8) - - await initialLease.release() - await newLease.release() - }).timeout(3 * MINUTES) - }) -}) diff --git a/test/e2e/integration/core/lease_renewal.test.ts b/test/e2e/integration/core/lease_renewal.test.ts new file mode 100644 index 000000000..e6950a726 --- /dev/null +++ b/test/e2e/integration/core/lease_renewal.test.ts @@ -0,0 +1,130 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { it, describe, before, after } from 'mocha' +import { ConfigManager, logging } from '../../../../src/core/index.js' +import { K8 } from '../../../../src/core/k8.js' +import { MINUTES, SECONDS } from '../../../../src/core/constants.js' +import { expect } from 'chai' +import { Lease } from '../../../../src/core/lease/lease.js' +import { LeaseHolder } from '../../../../src/core/lease/lease_holder.js' +import { sleep } from '../../../../src/core/helpers.js' +import { IntervalLeaseRenewalService } from '../../../../src/core/lease/lease_renewal.js' +import { type V1Lease } from '@kubernetes/client-node' + + +const defaultTimeout = 2 * MINUTES +const leaseDuration = 4 + +describe('LeaseRenewalService', async function () { + const testLogger = logging.NewLogger('debug', true) + const configManager = new ConfigManager(testLogger) + const k8 = new K8(configManager, testLogger) + const testNamespace = 'lease-renewal-e2e' + const renewalService = new IntervalLeaseRenewalService() + + before(async function () { + this.timeout(defaultTimeout) + if (await k8.hasNamespace(testNamespace)) { + await k8.deleteNamespace(testNamespace) + await sleep(5 * SECONDS) + } + + await k8.createNamespace(testNamespace) + }) + + after(async function () { + this.timeout(defaultTimeout) + await k8.deleteNamespace(testNamespace) + }) + + it('acquired leases should be scheduled', async function () { + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + await lease.acquire() + expect(lease.scheduleId).to.not.be.null + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.true + + await lease.release() + expect(lease.scheduleId).to.be.null + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.false + }) + + it('acquired leases should be renewed', async function () { + this.timeout(defaultTimeout) + + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + await lease.acquire() + expect(lease.scheduleId).to.not.be.null + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.true + + // @ts-ignore + let remoteObject: V1Lease = await lease.retrieveLease() + expect(remoteObject).to.not.be.null + expect(remoteObject?.spec?.renewTime).to.be.undefined + expect(remoteObject?.spec?.acquireTime).to.not.be.undefined + expect(remoteObject?.spec?.acquireTime).to.not.be.null + + const acquireTime = new Date(remoteObject?.spec?.acquireTime).valueOf() + expect(acquireTime).to.be.greaterThan(0) + + await sleep(lease.durationSeconds * SECONDS) + // @ts-ignore + remoteObject = await lease.retrieveLease() + expect(remoteObject).to.not.be.null + expect(remoteObject?.spec?.renewTime).to.not.be.undefined + expect(remoteObject?.spec?.renewTime).to.not.be.null + + const renewTime = new Date(remoteObject?.spec?.renewTime).valueOf() + expect(renewTime).to.be.greaterThan(acquireTime) + + await lease.release() + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.false + expect(lease.scheduleId).to.be.null + }) + + it('acquired leases with cancelled schedules should not be renewed', async function () { + this.timeout(defaultTimeout) + + const lease = new Lease(k8, renewalService, LeaseHolder.default(), testNamespace, null, leaseDuration) + await lease.acquire() + expect(lease.scheduleId).to.not.be.null + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.true + + expect(await renewalService.cancel(lease.scheduleId)).to.be.true + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.false + + + // @ts-ignore + let remoteObject: V1Lease = await lease.retrieveLease(k8) + expect(remoteObject).to.not.be.null + expect(remoteObject?.spec?.renewTime).to.be.undefined + expect(remoteObject?.spec?.acquireTime).to.not.be.undefined + expect(remoteObject?.spec?.acquireTime).to.not.be.null + + const acquireTime = new Date(remoteObject?.spec?.acquireTime).valueOf() + expect(acquireTime).to.be.greaterThan(0) + + await sleep(lease.durationSeconds * SECONDS) + // @ts-ignore + remoteObject = await lease.retrieveLease() + expect(remoteObject).to.not.be.null + expect(remoteObject?.spec?.renewTime).to.be.undefined + + await lease.release() + expect(await renewalService.isScheduled(lease.scheduleId)).to.be.false + // expect(lease.scheduleId).to.be.null + }) +}) diff --git a/test/e2e/integration/core/noop_lease_renewal_service.test.ts b/test/e2e/integration/core/noop_lease_renewal_service.test.ts new file mode 100644 index 000000000..1dd073636 --- /dev/null +++ b/test/e2e/integration/core/noop_lease_renewal_service.test.ts @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the ""License""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an ""AS IS"" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import type { Lease } from '../../../../src/core/lease/lease.js' +import { type LeaseRenewalService } from '../../../../src/core/lease/lease_renewal.js' + +export class NoopLeaseRenewalService implements LeaseRenewalService { + private readonly buffer: SharedArrayBuffer + private readonly counter: Uint32Array + + public constructor () { + this.buffer = new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT) + this.counter = new Uint32Array(this.buffer) + Atomics.store(this.counter, 0, 1) + } + + public async isScheduled (scheduleId: number): Promise { + return scheduleId > 0 + } + + public async schedule (lease: Lease): Promise { + return Atomics.add(this.counter, 0, 1) + } + + public async cancel (scheduleId: number): Promise { + return true + } + + public async cancelAll (): Promise> { + return new Map() + } + + public calculateRenewalDelay (lease: Lease): number { + return 10 + } +} diff --git a/test/e2e/integration/core/package_downloader_e2e.test.ts b/test/e2e/integration/core/package_downloader_e2e.test.ts index d602cab50..6c0a881e9 100644 --- a/test/e2e/integration/core/package_downloader_e2e.test.ts +++ b/test/e2e/integration/core/package_downloader_e2e.test.ts @@ -20,8 +20,8 @@ import { it, describe } from 'mocha' import { expect } from 'chai' import * as fs from 'fs' -import { logging, PackageDownloader, Templates } from '../../../../src/core/index.ts' -import { MINUTES } from '../../../../src/core/constants.ts' +import { logging, PackageDownloader, Templates } from '../../../../src/core/index.js' +import { MINUTES } from '../../../../src/core/constants.js' describe('PackageDownloaderE2E', () => { const testLogger = logging.NewLogger('debug', true) diff --git a/test/e2e/integration/core/platform_installer_e2e.test.ts b/test/e2e/integration/core/platform_installer_e2e.test.ts index cb70703b7..028cfd55f 100644 --- a/test/e2e/integration/core/platform_installer_e2e.test.ts +++ b/test/e2e/integration/core/platform_installer_e2e.test.ts @@ -17,7 +17,7 @@ import { it, describe, after, before } from 'mocha' import { expect } from 'chai' -import { constants } from '../../../../src/core/index.ts' +import { constants } from '../../../../src/core/index.js' import * as fs from 'fs' import { @@ -26,10 +26,10 @@ import { getTestCacheDir, TEST_CLUSTER, testLogger -} from '../../../test_util.ts' -import { flags } from '../../../../src/commands/index.ts' -import * as version from '../../../../version.ts' -import { MINUTES, SECONDS } from '../../../../src/core/constants.ts' +} from '../../../test_util.js' +import { flags } from '../../../../src/commands/index.js' +import * as version from '../../../../version.js' +import { MINUTES, SECONDS } from '../../../../src/core/constants.js' const defaultTimeout = 20 * SECONDS @@ -98,7 +98,7 @@ e2eTestSuite(namespace, argv, undefined, undefined, undefined, undefined, undefi }).timeout(defaultTimeout) it('should succeed with valid tag and pod', async () => { - await expect(installer.fetchPlatform(podName, packageVersion)).to.eventually.be.ok + expect(await installer.fetchPlatform(podName, packageVersion)).to.be.true const outputs = await k8.execContainer(podName, constants.ROOT_CONTAINER, `ls -la ${constants.HEDERA_HAPI_PATH}`) testLogger.showUser(outputs) }).timeout(MINUTES) diff --git a/test/test_add.ts b/test/test_add.ts index 63db5b381..f14e18536 100644 --- a/test/test_add.ts +++ b/test/test_add.ts @@ -17,7 +17,7 @@ import { expect } from 'chai' import { describe, it, after } from 'mocha' -import { flags } from '../src/commands/index.ts' +import { flags } from '../src/commands/index.js' import { accountCreationShouldSucceed, balanceQueryShouldSucceed, @@ -26,12 +26,12 @@ import { getNodeAliasesPrivateKeysHash, getTmpDir, HEDERA_PLATFORM_VERSION_TAG -} from './test_util.ts' -import { getNodeLogs } from '../src/core/helpers.ts' -import * as NodeCommandConfigs from '../src/commands/node/configs.ts' -import { MINUTES } from '../src/core/constants.ts' -import type { NodeAlias } from '../src/types/aliases.ts' -import type { NetworkNodeServices } from '../src/core/network_node_services.ts' +} from './test_util.js' +import { getNodeLogs } from '../src/core/helpers.js' +import * as NodeCommandConfigs from '../src/commands/node/configs.js' +import { MINUTES } from '../src/core/constants.js' +import type { NodeAlias } from '../src/types/aliases.js' +import type { NetworkNodeServices } from '../src/core/network_node_services.js' const defaultTimeout = 2 * MINUTES @@ -76,7 +76,7 @@ export function testNodeAdd (localBuildPath: string, testDescription = 'Node add }).timeout(defaultTimeout) it('should succeed with init command', async () => { - await expect(accountCmd.init(argv)).to.eventually.be.ok + expect(await accountCmd.init(argv)).to.be.true }).timeout(8 * MINUTES) it('should add a new node to the network successfully', async () => { diff --git a/test/test_util.ts b/test/test_util.ts index c6894657a..e63afb0c4 100644 --- a/test/test_util.ts +++ b/test/test_util.ts @@ -22,15 +22,16 @@ import { describe, it, after, before } from 'mocha' import fs from 'fs' import os from 'os' import path from 'path' -import { ClusterCommand } from '../src/commands/cluster.ts' -import { InitCommand } from '../src/commands/init.ts' -import { NetworkCommand } from '../src/commands/network.ts' -import { NodeCommand } from '../src/commands/node/index.ts' +import { flags } from '../src/commands/index.js' +import { ClusterCommand } from '../src/commands/cluster.js' +import { InitCommand } from '../src/commands/init.js' +import { NetworkCommand } from '../src/commands/network.js' +import { NodeCommand } from '../src/commands/node/index.js' import { DependencyManager, HelmDependencyManager -} from '../src/core/dependency_managers/index.ts' -import { getNodeLogs, sleep } from '../src/core/helpers.ts' +} from '../src/core/dependency_managers/index.js' +import { getNodeLogs, sleep } from '../src/core/helpers.js' import { ChartManager, ConfigManager, @@ -45,25 +46,24 @@ import { Templates, Zippy, AccountManager, CertificateManager -} from '../src/core/index.ts' -import { flags } from '../src/commands/index.ts' +} from '../src/core/index.js' import { AccountBalanceQuery, AccountCreateTransaction, Hbar, HbarUnit, PrivateKey } from '@hashgraph/sdk' -import { MINUTES, NODE_LOG_FAILURE_MSG, ROOT_CONTAINER, SECONDS, SOLO_LOGS_DIR } from '../src/core/constants.ts' +import { MINUTES, NODE_LOG_FAILURE_MSG, ROOT_CONTAINER, SECONDS, SOLO_LOGS_DIR } from '../src/core/constants.js' import crypto from 'crypto' -import { AccountCommand } from '../src/commands/account.ts' -import { SoloError } from '../src/core/errors.ts' +import { AccountCommand } from '../src/commands/account.js' +import { SoloError } from '../src/core/errors.js' import { execSync } from 'child_process' -import * as NodeCommandConfigs from '../src/commands/node/configs.ts' -import type { SoloLogger } from '../src/core/logging.ts' -import type { BaseCommand } from '../src/commands/base.ts' -import type { NodeAlias } from '../src/types/aliases.ts' -import type { NetworkNodeServices } from '../src/core/network_node_services.ts' -import sinon from 'sinon' +import * as NodeCommandConfigs from '../src/commands/node/configs.js' +import type { SoloLogger } from '../src/core/logging.js' +import type { BaseCommand } from '../src/commands/base.js' +import type { NodeAlias } from '../src/types/aliases.js' +import type { NetworkNodeServices } from '../src/core/network_node_services.js' import { HEDERA_PLATFORM_VERSION } from '../version.js' +import { IntervalLeaseRenewalService } from '../src/core/lease/lease_renewal.js' export const testLogger = logging.NewLogger('debug', true) export const TEST_CLUSTER = 'solo-e2e' @@ -150,7 +150,7 @@ export function bootstrapTestVariables ( const accountManager = new AccountManager(testLogger, k8) const platformInstaller = new PlatformInstaller(testLogger, k8, configManager) const profileManager = new ProfileManager(testLogger, configManager) - const leaseManager = new LeaseManager(k8, testLogger, configManager) + const leaseManager = new LeaseManager(k8, configManager, testLogger, new IntervalLeaseRenewalService()) const certificateManager = new CertificateManager(k8, testLogger, configManager) const opts: TestOpts = { @@ -243,7 +243,7 @@ export function e2eTestSuite ( }).timeout(2 * MINUTES) it('generate key files', async () => { - await expect(nodeCmd.handlers.keys(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.keys(argv)).to.be.true expect(nodeCmd.getUnusedConfigs(NodeCommandConfigs.KEYS_CONFIGS_NAME)).to.deep.equal([ flags.devMode.constName, flags.quiet.constName @@ -274,7 +274,7 @@ export function e2eTestSuite ( it('should succeed with node setup command', async () => { // cache this, because `solo node setup.finalize()` will reset it to false try { - await expect(nodeCmd.handlers.setup(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.setup(argv)).to.be.true expect(nodeCmd.getUnusedConfigs(NodeCommandConfigs.SETUP_CONFIGS_NAME)).to.deep.equal([ flags.devMode.constName ]) @@ -286,7 +286,7 @@ export function e2eTestSuite ( it('should succeed with node start command', async () => { try { - await expect(nodeCmd.handlers.start(argv)).to.eventually.be.ok + expect(await nodeCmd.handlers.start(argv)).to.be.true } catch (e) { nodeCmd.logger.showUserError(e) expect.fail() @@ -294,17 +294,12 @@ export function e2eTestSuite ( }).timeout(30 * MINUTES) it('node log command should work', async () => { - try { - await expect(nodeCmd.handlers.logs(argv)).to.eventually.be.ok + await expect(nodeCmd.handlers.logs(argv)).to.eventually.be.ok - const soloLogPath = path.join(SOLO_LOGS_DIR, 'solo.log') - const soloLog = fs.readFileSync(soloLogPath, 'utf8') + const soloLogPath = path.join(SOLO_LOGS_DIR, 'solo.log') + const soloLog = fs.readFileSync(soloLogPath, 'utf8') - expect(soloLog).to.not.contain(NODE_LOG_FAILURE_MSG) - } catch (e) { - nodeCmd.logger.showUserError(e) - expect.fail() - } + expect(soloLog).to.not.have.string(NODE_LOG_FAILURE_MSG) }).timeout(30 * MINUTES) } }) diff --git a/test/unit/commands/base.test.ts b/test/unit/commands/base.test.ts index 5f31ae2cb..e49693e35 100644 --- a/test/unit/commands/base.test.ts +++ b/test/unit/commands/base.test.ts @@ -16,7 +16,7 @@ */ import { expect } from 'chai' -import { HelmDependencyManager, DependencyManager } from '../../../src/core/dependency_managers/index.ts' +import { HelmDependencyManager, DependencyManager } from '../../../src/core/dependency_managers/index.js' import { ChartManager, ConfigManager, @@ -24,9 +24,9 @@ import { logging, PackageDownloader, Zippy, constants, K8 -} from '../../../src/core/index.ts' -import { BaseCommand } from '../../../src/commands/base.ts' -import * as flags from '../../../src/commands/flags.ts' +} from '../../../src/core/index.js' +import { BaseCommand } from '../../../src/commands/base.js' +import * as flags from '../../../src/commands/flags.js' import sinon from 'sinon' const testLogger = logging.NewLogger('debug', true) diff --git a/test/unit/commands/node.test.ts b/test/unit/commands/node.test.ts index e9952b1e3..efd93ccc4 100644 --- a/test/unit/commands/node.test.ts +++ b/test/unit/commands/node.test.ts @@ -18,7 +18,7 @@ import sinon from 'sinon' import { describe, it, beforeEach } from 'mocha' import { expect } from 'chai' -import { NodeCommand } from '../../../src/commands/node/index.ts' +import { NodeCommand } from '../../../src/commands/node/index.js' const getBaseCommandOpts = () => ({ logger: sinon.stub(), diff --git a/test/unit/core/certificate_manager.test.ts b/test/unit/core/certificate_manager.test.ts index ad2774de4..f705c36d3 100644 --- a/test/unit/core/certificate_manager.test.ts +++ b/test/unit/core/certificate_manager.test.ts @@ -18,10 +18,10 @@ import { expect } from 'chai' import { after, before, describe, it } from 'mocha' import jest from 'jest-mock' -import { CertificateManager, ConfigManager, K8 } from '../../../src/core/index.ts' -import { flags } from '../../../src/commands/index.ts' -import { testLogger } from '../../test_util.ts' -import { SoloError } from '../../../src/core/errors.ts' +import { CertificateManager, ConfigManager, K8 } from '../../../src/core/index.js' +import { flags } from '../../../src/commands/index.js' +import { testLogger } from '../../test_util.js' +import { SoloError } from '../../../src/core/errors.js' describe('Certificate Manager', () => { diff --git a/test/unit/core/config_manager.test.ts b/test/unit/core/config_manager.test.ts index db8a24206..4c66419d6 100644 --- a/test/unit/core/config_manager.test.ts +++ b/test/unit/core/config_manager.test.ts @@ -17,9 +17,9 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { ConfigManager } from '../../../src/core/index.ts' -import * as flags from '../../../src/commands/flags.ts' -import { testLogger } from '../../test_util.ts' +import { ConfigManager } from '../../../src/core/index.js' +import * as flags from '../../../src/commands/flags.js' +import { testLogger } from '../../test_util.js' describe('ConfigManager', () => { describe('update values using argv', () => { diff --git a/test/unit/core/dependency_managers/dependency_manager.test.ts b/test/unit/core/dependency_managers/dependency_manager.test.ts index f749c0509..4b6aa64aa 100644 --- a/test/unit/core/dependency_managers/dependency_manager.test.ts +++ b/test/unit/core/dependency_managers/dependency_manager.test.ts @@ -17,9 +17,9 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { DependencyManager, HelmDependencyManager } from '../../../../src/core/dependency_managers/index.ts' -import { logging, constants, PackageDownloader, Zippy } from '../../../../src/core/index.ts' -import { SECONDS } from '../../../../src/core/constants.ts' +import { DependencyManager, HelmDependencyManager } from '../../../../src/core/dependency_managers/index.js' +import { logging, constants, PackageDownloader, Zippy } from '../../../../src/core/index.js' +import { SECONDS } from '../../../../src/core/constants.js' const testLogger = logging.NewLogger('debug', true) describe('DependencyManager', () => { diff --git a/test/unit/core/errors.test.ts b/test/unit/core/errors.test.ts index c405e41bb..2fea96b67 100644 --- a/test/unit/core/errors.test.ts +++ b/test/unit/core/errors.test.ts @@ -23,7 +23,7 @@ import { MissingArgumentError, IllegalArgumentError, DataValidationError -} from '../../../src/core/errors.ts' +} from '../../../src/core/errors.js' describe('Errors', () => { const message = 'errorMessage' diff --git a/test/unit/core/helm.test.ts b/test/unit/core/helm.test.ts index 5e7d6805b..704950e5f 100644 --- a/test/unit/core/helm.test.ts +++ b/test/unit/core/helm.test.ts @@ -19,8 +19,8 @@ import { expect } from 'chai' import { afterEach, beforeEach, describe, it } from 'mocha' import each from 'mocha-each' -import { constants, Helm, logging, Templates } from '../../../src/core/index.ts' -import { ShellRunner } from '../../../src/core/shell_runner.ts' +import { constants, Helm, logging, Templates } from '../../../src/core/index.js' +import { ShellRunner } from '../../../src/core/shell_runner.js' describe('Helm platform specific tests', () => { each(['linux', 'windows', 'darwin']) diff --git a/test/unit/core/helpers.test.ts b/test/unit/core/helpers.test.ts index 2d8bbcae8..4f8a7f438 100644 --- a/test/unit/core/helpers.test.ts +++ b/test/unit/core/helpers.test.ts @@ -18,8 +18,8 @@ import { expect } from 'chai' import { describe, it } from 'mocha' import each from 'mocha-each' -import * as helpers from '../../../src/core/helpers.ts' -import { HEDERA_PLATFORM_VERSION } from '../../../version.ts' +import * as helpers from '../../../src/core/helpers.js' +import { HEDERA_PLATFORM_VERSION } from '../../../version.js' describe('Helpers', () => { each([ diff --git a/test/unit/core/k8.test.ts b/test/unit/core/k8.test.ts index 04528745f..35414055a 100644 --- a/test/unit/core/k8.test.ts +++ b/test/unit/core/k8.test.ts @@ -18,10 +18,10 @@ import { expect } from 'chai' import { describe, it, after, before } from 'mocha' import jest from 'jest-mock' -import { ConfigManager, constants, K8 } from '../../../src/core/index.ts' -import { testLogger } from '../../test_util.ts' -import { flags } from '../../../src/commands/index.ts' -import { SECONDS } from '../../../src/core/constants.ts' +import { ConfigManager, constants, K8 } from '../../../src/core/index.js' +import { testLogger } from '../../test_util.js' +import { flags } from '../../../src/commands/index.js' +import { SECONDS } from '../../../src/core/constants.js' function listNamespacedPodMockSetup (k8: K8, numOfFailures: number, result: any) { for (let i = 0; i < numOfFailures - 1; i++) { // @ts-ignore diff --git a/test/unit/core/key_manager.test.ts b/test/unit/core/key_manager.test.ts index c7c29c15d..4fede7610 100644 --- a/test/unit/core/key_manager.test.ts +++ b/test/unit/core/key_manager.test.ts @@ -20,9 +20,9 @@ import { describe, it } from 'mocha' import fs from 'fs' import os from 'os' import path from 'path' -import { constants, logging, KeyManager } from '../../../src/core/index.ts' -import { SECONDS } from '../../../src/core/constants.ts' -import type { NodeAlias } from '../../../src/types/aliases.ts' +import { constants, logging, KeyManager } from '../../../src/core/index.js' +import { SECONDS } from '../../../src/core/constants.js' +import type { NodeAlias } from '../../../src/types/aliases.js' describe('KeyManager', () => { const logger = logging.NewLogger('debug', true) @@ -45,10 +45,10 @@ describe('KeyManager', () => { expect(nodeKey.privateKey.algorithm).to.deep.equal(signingKey.privateKey.algorithm) expect(nodeKey.privateKey.type).to.deep.equal(signingKey.privateKey.type) - await expect(signingKey.certificate.verify({ + expect(await signingKey.certificate.verify({ publicKey: signingKey.certificate.publicKey, signatureOnly: true - })).to.eventually.be.ok + })).to.be.true fs.rmSync(tmpDir, { recursive: true }) }) @@ -72,10 +72,10 @@ describe('KeyManager', () => { expect(nodeKey.privateKey.algorithm).to.deep.equal(tlsKey.privateKey.algorithm) expect(nodeKey.privateKey.type).to.deep.equal(tlsKey.privateKey.type) - await expect(tlsKey.certificate.verify({ + expect(await tlsKey.certificate.verify({ publicKey: tlsKey.certificate.publicKey, signatureOnly: true - })).to.eventually.be.ok + })).to.be.true fs.rmSync(tmpDir, { recursive: true }) }).timeout(20 * SECONDS) diff --git a/test/unit/core/logging.test.ts b/test/unit/core/logging.test.ts index 170fa261c..23e2af07b 100644 --- a/test/unit/core/logging.test.ts +++ b/test/unit/core/logging.test.ts @@ -21,7 +21,7 @@ import sinon from 'sinon' import { expect } from 'chai' import { describe, it, afterEach, beforeEach } from 'mocha' -import { NewLogger, SoloLogger } from '../../../src/core/logging.ts' +import { NewLogger, SoloLogger } from '../../../src/core/logging.js' import winston from 'winston' describe('Logging', () => { diff --git a/test/unit/core/package_downloader.test.ts b/test/unit/core/package_downloader.test.ts index ca8ec0516..818adfe46 100644 --- a/test/unit/core/package_downloader.test.ts +++ b/test/unit/core/package_downloader.test.ts @@ -17,11 +17,11 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import * as core from '../../../src/core/index.ts' +import * as core from '../../../src/core/index.js' import * as fs from 'fs' import * as path from 'path' import * as os from 'os' -import { IllegalArgumentError, MissingArgumentError, ResourceNotFoundError } from '../../../src/core/errors.ts' +import { IllegalArgumentError, MissingArgumentError, ResourceNotFoundError } from '../../../src/core/errors.js' describe('PackageDownloader', () => { const testLogger = core.logging.NewLogger('debug', true) diff --git a/test/unit/core/platform_installer.test.ts b/test/unit/core/platform_installer.test.ts index 3d1f85518..fd8e6bb0f 100644 --- a/test/unit/core/platform_installer.test.ts +++ b/test/unit/core/platform_installer.test.ts @@ -17,14 +17,14 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import * as core from '../../../src/core/index.ts' -import { ConfigManager, PlatformInstaller } from '../../../src/core/index.ts' +import * as core from '../../../src/core/index.js' +import { ConfigManager, PlatformInstaller } from '../../../src/core/index.js' import * as fs from 'fs' import * as path from 'path' import * as os from 'os' -import { IllegalArgumentError, MissingArgumentError } from '../../../src/core/errors.ts' -import { getK8Instance } from '../../test_util.ts' -import type { PodName } from '../../../src/types/aliases.ts' +import { IllegalArgumentError, MissingArgumentError } from '../../../src/core/errors.js' +import { getK8Instance } from '../../test_util.js' +import type { PodName } from '../../../src/types/aliases.js' describe('PackageInstaller', () => { const testLogger = core.logging.NewLogger('debug', true) diff --git a/test/unit/core/profile_manager.test.ts b/test/unit/core/profile_manager.test.ts index 7a53fe419..d75367c59 100644 --- a/test/unit/core/profile_manager.test.ts +++ b/test/unit/core/profile_manager.test.ts @@ -20,15 +20,15 @@ import { describe, it, after } from 'mocha' import fs from 'fs' import * as yaml from 'js-yaml' import path from 'path' -import { flags } from '../../../src/commands/index.ts' +import { flags } from '../../../src/commands/index.js' import { ConfigManager, constants, ProfileManager -} from '../../../src/core/index.ts' -import { getTestCacheDir, getTmpDir, testLogger } from '../../test_util.ts' -import * as version from '../../../version.ts' -import type { NodeAlias } from '../../../src/types/aliases.ts' +} from '../../../src/core/index.js' +import { getTestCacheDir, getTmpDir, testLogger } from '../../test_util.js' +import * as version from '../../../version.js' +import type { NodeAlias } from '../../../src/types/aliases.js' const tmpDir = getTmpDir() const configManager = new ConfigManager(testLogger) diff --git a/test/unit/core/shell_runner.test.ts b/test/unit/core/shell_runner.test.ts index 6e223707d..cd5d545ac 100644 --- a/test/unit/core/shell_runner.test.ts +++ b/test/unit/core/shell_runner.test.ts @@ -20,11 +20,11 @@ import type { SinonSpy, SinonStub } from 'sinon' import sinon from 'sinon' import { expect } from 'chai' import { describe, it, beforeEach, afterEach } from 'mocha' -import { ShellRunner } from '../../../src/core/shell_runner.ts' -import { NewLogger, SoloLogger } from '../../../src/core/logging.ts' +import { ShellRunner } from '../../../src/core/shell_runner.js' +import { NewLogger, SoloLogger } from '../../../src/core/logging.js' import { ChildProcess } from 'child_process' import { Readable } from 'stream' -import { SECONDS } from '../../../src/core/constants.ts' +import { SECONDS } from '../../../src/core/constants.js' describe('ShellRunner', () => { let logger: SoloLogger, diff --git a/test/unit/core/zippy.test.ts b/test/unit/core/zippy.test.ts index c2d432908..a093ca928 100644 --- a/test/unit/core/zippy.test.ts +++ b/test/unit/core/zippy.test.ts @@ -19,12 +19,12 @@ import 'chai-as-promised' import { expect } from 'chai' import { describe, it } from 'mocha' -import * as core from '../../../src/core/index.ts' -import { IllegalArgumentError, MissingArgumentError, SoloError } from '../../../src/core/errors.ts' +import * as core from '../../../src/core/index.js' +import { IllegalArgumentError, MissingArgumentError, SoloError } from '../../../src/core/errors.js' import os from 'os' import fs from 'fs' import path from 'path' -import { Zippy } from '../../../src/core/zippy.ts' +import { Zippy } from '../../../src/core/zippy.js' describe('Zippy', () => { const testLogger = core.logging.NewLogger('debug', true) diff --git a/tsconfig.json b/tsconfig.json index 9b930696b..c4dc2ef23 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Visit https://aka.ms/tsconfig to read more about this file */ /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ @@ -12,7 +12,10 @@ /* Language and Environment */ "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - "lib": ["ES2022", "dom"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": [ + "ES2022", + "dom" + ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ @@ -22,44 +25,45 @@ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - "moduleDetection": "force", /* Control what method is used to detect module-format JS files. */ - - "importsNotUsedAsValues": "remove", - /* Modules */ + "moduleDetection": "force", /* Control what method is used to detect module-format JS files. */ + "importsNotUsedAsValues": "remove", /* Modules */ "module": "NodeNext", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ -// "moduleResolution": "Node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - "types": ["node", "mocha"], /* Specify type package names to be included without being referenced in a source file. */ + "types": [ + "node", + "mocha" + ], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ -// "resolveJsonModule": true, /* Enable importing .json files. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, requires or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ -// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ -// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ -// "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - "noEmit": true, /* Disable emitting files from a compilation. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ - "removeComments": false, /* Disable emitting comments. */ + "outDir": "dist", /* Specify an output folder for all emitted files. */ + "removeComments": false, /* Disable emitting comments. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ @@ -74,16 +78,16 @@ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ /* Interop Constraints */ -// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ -// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ - "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ - "strict": false, /* Enable all strict type-checking options. */ + "strict": false, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -96,7 +100,7 @@ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - "noImplicitReturns": true, /* Enable error reporting for code paths that do not explicitly return in a function. */ + "noImplicitReturns": true, /* Enable error reporting for code paths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ // future improvement // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // future improvement @@ -115,6 +119,11 @@ "test" ], "ts-node": { - "esm": true + "esm": true, + "experimentalResolver": true, + "showConfig": true, + "compilerHost": true, + "emit": true, + "experimentalSpecifierResolution": "node" } } diff --git a/version.ts b/version.ts index 01f3f8d04..4d8d1e365 100644 --- a/version.ts +++ b/version.ts @@ -21,7 +21,7 @@ export const JAVA_VERSION = '21.0.1+12' export const HELM_VERSION = 'v3.14.2' -export const SOLO_CHART_VERSION = '0.34.0' +export const SOLO_CHART_VERSION = '0.34.1' export const HEDERA_PLATFORM_VERSION = 'v0.56.0' export const MIRROR_NODE_VERSION = '0.116.0' export const HEDERA_EXPLORER_VERSION = '0.2.1'