diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 9c43d31b..00000000 --- a/.eslintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - "rules": { - "@typescript-eslint/ban-ts-comment": "warn" - } -} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1badd084..cf1d558c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,19 +7,38 @@ on: branches: - master +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false # don't cancel all jobs if some of them failed matrix: - node: ["20"] + node: ["22", "24", "26"] steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - run: yarn install + - run: yarn install --frozen-lockfile - run: yarn lint + - run: yarn build - run: yarn test + + # Live Docker / IPFS / Ethereum checks (previously part of `yarn test`). + # Kept visible but non-blocking, since they depend on external services. + integration: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: "24" + - run: yarn install --frozen-lockfile + - run: yarn build + - run: yarn test:integration diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25b636ce..d54fecd7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: registry-url: https://registry.npmjs.org/ - name: Install dependencies - run: yarn + run: yarn install --frozen-lockfile - name: Compare versions run: | diff --git a/.github/workflows/test-ga-build.yml b/.github/workflows/test-ga-build.yml index 8d29e144..3f406de3 100644 --- a/.github/workflows/test-ga-build.yml +++ b/.github/workflows/test-ga-build.yml @@ -5,16 +5,23 @@ on: branches: - master +permissions: + contents: read + # The build bot creates/updates its comment through the issues API; on a pull + # request GitHub requires pull-requests: write for that. + issues: write + pull-requests: write + jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Node.js 20.x + - name: Set up Node.js 24.x uses: actions/setup-node@v4 with: - node-version: 20.x - - run: yarn install + node-version: 24.x + - run: yarn install --frozen-lockfile - run: yarn build # Simulate Github Actions run on an actual DAppNode package diff --git a/.github/workflows/test-ga-bump-upstream-template.yml b/.github/workflows/test-ga-bump-upstream-template.yml index a10a8bb5..37a10874 100644 --- a/.github/workflows/test-ga-bump-upstream-template.yml +++ b/.github/workflows/test-ga-bump-upstream-template.yml @@ -9,16 +9,21 @@ env: ENVIRONMENT: TEST INITIAL_VERSION: "0.1.0" +permissions: + contents: write # bump branch + pull-requests: write # bump PR + issues: write # build bot comment + jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Node.js 20.x + - name: Set up Node.js 24.x uses: actions/setup-node@v4 with: - node-version: 20.x - - run: yarn install + node-version: 24.x + - run: yarn install --frozen-lockfile - run: yarn build # Simulate Github Actions run on an actual DAppNode package diff --git a/.github/workflows/test-ga-bump-upstream.yml b/.github/workflows/test-ga-bump-upstream.yml index 8b9f4276..f75462fb 100644 --- a/.github/workflows/test-ga-bump-upstream.yml +++ b/.github/workflows/test-ga-bump-upstream.yml @@ -9,16 +9,21 @@ env: ENVIRONMENT: TEST INITIAL_VERSION: "0.1.0" +permissions: + contents: write # bump branch + pull-requests: write # bump PR + issues: write # build bot comment + jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Node.js 20.x + - name: Set up Node.js 24.x uses: actions/setup-node@v4 with: - node-version: 20.x - - run: yarn install + node-version: 24.x + - run: yarn install --frozen-lockfile - run: yarn build # Simulate Github Actions run on an actual DAppNode package diff --git a/.mocharc.yml b/.mocharc.yml index cf151954..802d94c7 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -1,9 +1,12 @@ colors: true -exit: true extension: [ts] +import: + - tsx require: - dotenv/config - - ts-node/register -node-option: - - experimental-specifier-resolution=node - - loader=ts-node/esm +spec: + - test/**/*.test.ts +ignore: + - test/commands/build.test.ts + - test/tasks/generatePublishTx.test.ts + - test/utils/versions/getNextPackageVersion.test.ts diff --git a/README.md b/README.md index 23d58fec..d9d72cdb 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,17 @@ Only generates the IPFS Hash to be able to install it without needing to create $ dappnodesdk build ``` +### Root and variant files + +In a multi-variant package (`--all_variants` or `--variants`), each release is assembled from the package root and the variant directory (`package_variants/` by default): + +- `dappnode_package.json` and `docker-compose.yml` are deep-merged, with the variant overriding the root. +- `setup-wizard.*` fields are merged by `id`, and `notifications.yaml` endpoints by `correlationId`. Within a matched entry, the variant's values override the root's, and an array from the variant (for example `enum`, `conditions` or `alerts`) replaces the root's array. The release contains exactly what was validated. +- Single files (avatar, `prometheus-targets.*`, `disclaimer.md`, `getting-started.md`, `setup.schema.json`, `setup-target.json`, `setup-ui.json`, `signature.json`) are taken from the variant directory when it has one, and otherwise from the root. +- Grafana dashboards (`*grafana-dashboard.json`) are collected from both the root and the variant. + +Schema validation coerces some values (for example `isBanner: "false"` becomes `false`). The release ships the coerced value, and the build prints a warning in the "Validate files" step so the source file can be fixed. + ## Publish It does the build of the image and shows the necessary transaction to be able to publish the package. The first time will create the repository but the rest will be updates of it. @@ -126,11 +137,21 @@ services: The dappnode SDK ueses the following internal dependencies to avoid code duplication across the `dappnodeSDK`, `DNP_DAPPMANAGER` and `sdk-publish` modules: - `@dappnode/types` -- `@dappnode/toolkit` - `@dappnode/schemas` In order to have a better developing experience these modules lives inside the DNP_DAPPMANAGER repository +## Development + +Use Node.js 22.13+ or Node.js 24+ (Node.js 20 reached end of life in April 2026), and install the exact locked dependencies with `yarn install --frozen-lockfile`. + +- `yarn lint` checks source and tests without changing files; `yarn lint:fix` applies automatic fixes. +- `yarn build` checks and compiles the SDK. +- `yarn test` runs deterministic regressions using temporary files, mocked Docker commands, and localhost HTTP servers. It does not need external credentials. +- `yarn test:integration` runs the live Docker/IPFS/Ethereum tests and requires those services to be available. + +Terminal builds show numbered package/architecture stages and recent complete log lines; uploads display a separate waiting-for-pinning phase after transmission. + ## License This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..a15249af --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,14 @@ +import js from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist/**", "node_modules/**", "test_files/**"] }, + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ["**/*.ts"], + rules: { + "@typescript-eslint/no-unused-vars": ["error", { caughtErrors: "none" }] + } + } +); diff --git a/package.json b/package.json index 7c4bbbd1..d1693051 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,13 @@ "bin": "dist/dappnodesdk.js", "scripts": { "tag-and-publish": "npm version patch && git push --follow-tags", - "test": "mocha \"./{,!(node_modules)/**}/*.test.ts\"", - "lint": "eslint . --ext .ts --fix", - "build": "tsc", + "test": "mocha", + "lint": "eslint src test --max-warnings 0", + "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc", "prepublish": "npm run build", - "pre-commit": "npm run lint && npm run test" + "pre-commit": "npm run lint && npm run test", + "test:integration": "mocha --no-config --import=tsx --require=dotenv/config --timeout 120000 \"test/commands/build.test.ts\" \"test/tasks/generatePublishTx.test.ts\" \"test/utils/versions/getNextPackageVersion.test.ts\"", + "lint:fix": "npm run lint -- --fix" }, "repository": { "type": "git", @@ -35,63 +37,60 @@ "homepage": "https://github.com/dappnode/DAppNodeSDK#readme", "dependencies": { "@dappnode/schemas": "^0.1.26", - "@dappnode/toolkit": "^0.1.21", "@dappnode/types": "^0.1.41", - "@octokit/rest": "^20.1.1", + "@octokit/rest": "^22.0.1", "async-retry": "^1.2.3", "chalk": "^2.4.2", "cli-progress": "^3.8.2", - "dockerode": "^3.3.5", - "dotenv": "^8.2.0", - "ethers": "6.3.0", + "dotenv": "^16.6.1", + "ethers": "^6.17.0", "figlet": "^1.2.3", - "form-data": "^3.0.0", - "got": "^12.6.1", - "graphql": "^16.6.0", - "image-size": "^0.8.1", - "inquirer": "^6.2.1", - "js-yaml": "^4.1.0", + "form-data": "^4.0.6", + "got": "^14.6.6", + "image-size": "^2.0.4", + "inquirer": "^12.11.1", + "js-yaml": "^4.3.2", "listr": "^0.14.3", - "lodash-es": "^4.17.21", + "lodash-es": "^4.18.1", + "log-update": "^6.1.0", "mime-types": "^2.1.24", "moment": "^2.27.0", "prettier": "^2.1.2", - "request": "^2.88.2", - "rimraf": "^3.0.2", "semver": "^7.6.0", "source-map-support": "^0.5.19", - "tar-fs": "^2.0.0", + "tar-fs": "^3.1.3", "timestring": "^5.0.1", - "yargs": "^17.7.1" + "yargs": "^17.7.1", + "wrap-ansi": "^9.0.2" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@types/async-retry": "^1.4.2", "@types/chai": "^4.3.4", "@types/cli-progress": "^3.7.0", - "@types/dockerode": "^3.3.16", "@types/figlet": "^1.2.0", - "@types/inquirer": "^6.5.0", - "@types/js-yaml": "^3.12.5", + "@types/js-yaml": "^4.0.9", "@types/listr": "^0.14.2", "@types/lodash-es": "^4.17.7", "@types/mime-types": "^2.1.0", "@types/mocha": "^10.0.1", - "@types/node": "^22.7.5", + "@types/node": "^20.19.0", "@types/prettier": "^2.1.5", - "@types/request": "^2.48.5", - "@types/rimraf": "^3.0.0", "@types/semver": "^7.3.1", "@types/tar-fs": "^2.0.0", "@types/yargs": "^17.0.24", - "@typescript-eslint/eslint-plugin": "^3.5.0", - "@typescript-eslint/parser": "^3.5.0", "chai": "^5.1.0", - "eslint": "^7.3.1", - "mocha": "^10.2.0", - "ts-node": "^10.9.1", - "typescript": "^5.6.3" + "eslint": "^10.14.0", + "mocha": "^12.0.3", + "tsx": "^4.23.15", + "typescript": "~5.9.3", + "typescript-eslint": "^8.72.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.13.0" + }, + "resolutions": { + "minimatch": "^11.0.1", + "mocha/glob": "^14.0.2" } } diff --git a/src/assets/defaultAvatar.ts b/src/assets/defaultAvatar.ts index c88c2889..84026ee4 100644 --- a/src/assets/defaultAvatar.ts +++ b/src/assets/defaultAvatar.ts @@ -1,2 +1 @@ -/* eslint-disable max-len */ export default "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAFrUExURQAAAElJSXl5eQYGBjQ0NAAAAAwMDEdwTMnJyZaWliQkJCoqKhsbGxAQEBYWFi8vL/n5+Xd3d1hYWODg4MXFxWhoaDk5OT4+PktLS7u7u/n5+erq6m5ubra2tpqamkRERDQ0NL6+vvn5+XV1dWdnZ2BgYFFRUX9/fyoqKsPDw21tbX5+fmpqaqampn19fY2Njb29vY6OjqSkpF5eXubm5mFhYe/v79nZ2YiIiNnZ2WBgYKSkpISEhDQ0NIeHh5mZmczMzPv7+11dXZycnNnZ2dzc3KysrO/v71BQUJycnEdHR8LCwpycnH9/f4yMjPb29nV1dfz8/Do6Ore3t1NTU6qqqs3NzY+Pj93d3Xh4eMfHx9vb219fX2BgYHt7e1ZWVrm5ubGxsZWVla+vr4GBgby8vOnp6cvLy8zMzODg4LKysqOjo1BQUJ+fn/v7+0xMTFJSUm1tbWhoaOXl5a6urj4+Pru7u/Pz8z4+Pkng8hIAAAB5dFJOU00HSE1NSk0AAU1NTU1NTUwOBE0FAjVNTE1JFwgMSQdNKkggTU1NTSJLDUwVPAxNTRYRShgVQQsSHBwuFU1JMiE4HRBNKSFNNz5ESCsnLEckMS1FIkU/RT1CQDI6SB83ODo0NytGQS1BSzIbOSkuJyNJRSlFR0BMPTB3Aql1AAAK30lEQVR42u2dZ0PiTBeGwfBS0pAQQwQku9KW3hHQVUSxK9h773XV1d39+e+ELTYIE4qiz8xnmOTKzJw5U859FJoPUhQIBIEgEASCQBAIAkEgCASBIBAEgkAQCAJBIAgEgSAQBIJAEIi8YrTZCncb1zPrAYPx3YKwyYC1M+QiFaCoOfuPnDVpeH8gybhvesSrUjwqOKPbioXj7wnElncv23lS8aKoOUdoc978PkCGJzNjjF5RseCCt3h51OIg1p/n2wJBKqoUNW7yb637WhOENXiOZyYISq2AKzT59eZw3cCyrQRi9Fg3f3j1sAz/CkZe61Z8AUtrgJjDsfE/RrbC6+IEJUHD2XWx3jj7xiCDA7c6p0riNUnOuT192eEVcIkf4a6+jDsffysQ9mi66DBJjWyCsX8b6BZnwcL8ZpuXk/gppWK8t5ODrw8yn93yczgmYZmEYKe7t+fhH56wbzLESHGTesa/O/lqICyr/L6YUJGU1KhwRj9bA8nnf9V6rOHONpPEP9U0fr+8kmNZbZNBLLapkxmexCo2BUbjcwcr7spmlTX4vo8vEHRlE4dRnL1zV2kxNgvE1uOLRR2E5EzHJ/rXYOo63fHPqSS7GRNa8/W2Nx5kML3pD/LV5mzKnomF03A1Ro6KqwwnaZgd4wMD3Y0EGdy/tbv0GNQcR/COi8tZG5yLnHd39Lmk2pgUvL+mjsINATnd67jWk3ImbJrgx/rXh+GcAnNvLGoX1FK1CQtb2UIdIFqtNrWyek/QmEJ2AWNe8B+atVDGByzApkcYXNIxExKHU1qp6hQV16jK47uNL+oaIP7BqL9sRBeVNhhXSms0HH2+MZFUZXOIkRMzS1abhZUB0h6JZPt4qYmCpCFp1Cb7j81ID5RfqD0bXR4z4RW7GabAVN6ufl/Z2l6AGAZTZzqn1ACkOWa1mGEkvaenrhQTWk6lYaYF0HVmL6dvJKsmXcHFVDpQBYR1b3sFKZOoZ0KZqYJHo0nPu/ccJtieh3HM3vTwGQyLljWXqpZaFKicYxfD0i1CSLwazffNxMLmh34tOvAMdMOQ3MT27igL1TCWeGxZJ1k1OSIN8r+KnqxjZNPqsTx7YDJpdZ8EOdglFUWqFpZX5uEciaQ19iNYuWFCskEwNTlxsDRZcYcNGLjD8Q095CIXwyhTW1faZoRpGlD1eXShfNU6eSAUzo2d/4xUf2b3jt9FkLBjhmSG+nMeSFcKVM2/rFoGiBp3rRbXhqH9tsJpf4JRwRtm79Dm2aANaszkT4tjTtWTWQYeBA8tpuTuC1ivpi7sLnjDzAf9U7Bf6mxnRKgJhBIWPl2Oyt8VMJ+lFu0CbCdT6/mO4mlv1VpH18C+H17rGAFW5h7Wyjzxnjy57JATtmEwkvjq31mXMGCji2DGp+sa7MBm0aqbuxWlUWbTsEbl1FLbHKmGdczw65nvKZvxhQ8WXzqYIMv4fLqa5hHaNbSVC7TLbhrDynLChFOQMBhn7wpb29mHdp0eqbgk1dU4IQIvw6HbTJltsmEKux0OE/z8z+gysXQPGGmxoSAvYQJrBvltZex+97D8hrmavL1xmKANM+dsy4SkdvTrBimtZYWb4pr8nTRPOvVNBz3+FdV7Y70gpRGDT/gXs7JZtO0Rz2FQkL3X3TyQ0uYTPgGsjEGuMTPaIt+jG0Q9K8/Ggvym0XtHDq0e+XPm2vHqHEG+FgicOwsWKZOpcI/8w63R/g6XSibM44aEB5n5Jb1Me7RsdNq/zRfknj1rtWl3xk5BU+hdwf0vtYAsadKp5RBDQC7/nNv9p2l5Rnn/4pcL7lPRfPBgc35Q87UWkM/ipnU8ApZpcIZGjauut9ZzcBDK0T2/gMPNLOLi1NfjEV+nNhDt3x14sEzbIDAYQ6Om9Ym7XYPUfQ2jwbC/dDAH5bdgGMnPHFv+bY0l6wL53Z8HD1fBF8Tg+kHoJPbydKTkx3pyJ8AthqqGIrnE4s/I4+1FS90gpZIf3RvjCbjuoHdEp3zPjjjBNq+/D3I+pIX7juxwaadL03AQ0Zud3b9wQq4Aad5+6c7/WTIFCgPf+qq5T4/61OqR9TlFQ0HEEp93n3shPyzhWshMzs4OTyecnJw5gyqWPzBrKIg4YHtyi0NOSMNM8IwKl+mSUB2vAyKyWGzukwMTVb/T9MYgvw942ex44itJvXeQP8Zop0N+33mYeeSAJJsKIjobskfz36sRiXtMBki7qskgon3tFu0rDg/x2zoHPlEtBlIyzL29kCtAlWNkz1e6RfNJ3YIg4nAMWJdEx0zqnBR4MLnA3xunrQpSsmWGqZJXiJVxn+ZuDnef3O9oYZA/zgzw0/knLYNzzFb2xVbSK4B01gVS2prbZx5xXB6VW3e9CxCN5uDRzZLyv5AHon8rkLZHhkqJQBAIAkEgCASBIBAEgkAQSCNByK33DwJu2S6Mr1veNwhGErx/p7vM9vV7AqH1rrH+02GNxGPfAQju8l5MXVW76NLSIJgCE+x37jOYWLFWBsk4dZ05TxKuulYGMdiM8DFIrQwiq3wckC8fBCReE0hX64GYEQgCQSAIBIEgEASCQBAIAvnPgAwSHwSkG4EgEASCQBAIAkEgCASBIJD/DEjhg4BoZ/EPcj5S2woxqmk5kNOaWoSem1kBAevalgAx2nzfowtErfHsGAiTncx5jG8M0h7Jjb+IxJQdmE/xwd3UWfytQHrSqduyCmw1KQyIMrHVL1g0HiQ+edtWSb2jVqkEkmNAwHr+FUGudos3EnoqtWs+YGpS71qFDVivD0T5c9lfReGmTvEKNf1l427HYDM2C4Q1gnD3NlN1zaEqIHCR5nyfGLCubTiIxWOFVoGqArLtImD1C4amfPFGgph7e6F1uXAusSYNwgLJMtiAdUrwgpDIcCNAPIWBiyBkOCYtOPqnh59fjHopAarVhM/c0oKvjxuGv87sztYHcrVWhNauUzl1xZS5jKRMBVHW9lLAOuQXwoWx89FAjSADWVFNUAE5NKM5UWK+3OCsLJMLAtZjJ20TUHoVGCVKOfa8dMykQIAcx9L4Ak7DND2m1m90uqWUaqWFi4HC7vp4goMLWBcds/5n2uSVQIBeOVDcNEHVq6aJidXjfBXtYBgp6QIIWOcgJUD44Eis90EWrSyIJezbh9VAJfX89t5oddFAWHHvwvD0tgMyYJ1gQlsD+UogeSB9AatKq2cWLvav4N4QXm7dNggfsE5xzK/+o8iTyFCVVmObvcw4BWgxkuhmPgD9evIE8HsikZ2gANezSW7Cnw0++rzrywuwakF6MNp8PbK07uSmJNBaAkoQsI5DKgnRj8mgFDtE6euTXEXp64aBlGZ/lh1YWp3D6UZLiVCkKbE4y9aUJab2tB3a9b0ErJIQTOvh3PVWtvaESnUlUrHN7mfsPFE/BW5ybE8fndXzLnWntgEpUlbtdUkWqhw336BTKDQPBJRA3JfWOfBaIGhX35ov7GnASzQq/VPS2nvcJ8ga/mq9t2vHGmhQMrsGJuRiWStIkaKHEcYV063MrPgal8WqCSnSJrP+e06ym5GEK3G+1ujnNiNpnRKkU3JydPnuxHuBclgT0gk2J42gFiS4eil0C1zjDnc+3ZQnNjOxo5hyrO+f9LDKGz3zmZuX2bG5qTbB9s5ml4Mg+dB6JJBs6qOanvyUNRqyK0qbsdnPQVlcEQgCQSAIBIEgEASCQBAIAkEgCASBIBAEgkBgyv8BoCGh7uNnhxQAAAAASUVORK5CYII="; diff --git a/src/commands/build/handler.ts b/src/commands/build/handler.ts index 137443cd..f67b4b7c 100644 --- a/src/commands/build/handler.ts +++ b/src/commands/build/handler.ts @@ -1,3 +1,4 @@ +import { getRendererOptions } from "../../utils/progress.js"; import Listr from "listr"; import { Architecture, architectures } from "@dappnode/types"; import { buildAndUpload } from "../../tasks/buildAndUpload/index.js"; @@ -51,7 +52,9 @@ export async function buildHandler({ for (const pkg of packagesToBuildProps) { if (!pkg.architectures.includes(architecture)) throw Error( - `Architecture '${architecture}' is not supported by package ${pkg.manifest.name}. Supported: ${pkg.architectures.join(", ")}` + `Architecture '${architecture}' is not supported by package ${ + pkg.manifest.name + }. Supported: ${pkg.architectures.join(", ")}` ); pkg.architectures = [architecture]; } @@ -66,15 +69,17 @@ export async function buildHandler({ skipUpload, composeFileName, requireGitData, + deleteOldPins, variantsDirPath, skipComposeValidation, stripComposeVersion, packagesToBuildProps }; - const verbosityOptions: VerbosityOptions = { - renderer: verbose ? "verbose" : silent ? "silent" : "default" - }; + const verbosityOptions: VerbosityOptions = getRendererOptions({ + verbose, + silent + }); const buildTasks = new Listr(buildAndUpload(buildOptions), verbosityOptions); @@ -94,7 +99,9 @@ export function normalizeArchitecture(arch: string): Architecture { const normalized = archShorthands[arch] ?? arch; if (!architectures.includes(normalized as Architecture)) throw Error( - `Invalid architecture '${arch}', allowed values: ${architectures.join(", ")} (or shorthands: ${Object.keys(archShorthands).join(", ")})` + `Invalid architecture '${arch}', allowed values: ${architectures.join( + ", " + )} (or shorthands: ${Object.keys(archShorthands).join(", ")})` ); return normalized as Architecture; } diff --git a/src/commands/build/index.ts b/src/commands/build/index.ts index c17bc639..5e3b0565 100644 --- a/src/commands/build/index.ts +++ b/src/commands/build/index.ts @@ -74,7 +74,10 @@ export const build: CommandModule = { handler: async (args): Promise => { const buildResults = await buildHandler(args); - printBuildResults(buildResults, Boolean(args.skipUpload)); + printBuildResults( + buildResults, + Boolean(args.skip_upload || args.skip_save) + ); } }; @@ -89,8 +92,9 @@ function printBuildResults( for (const [dnpName, { releaseMultiHash }] of Object.entries(buildResults)) { if (!releaseMultiHash) { - console.log(chalk.red(`Error building Dappnode Package (${dnpName})\n`)); - return; + throw new Error( + `No uploaded release hash for Dappnode Package (${dnpName})` + ); } console.log(` diff --git a/src/commands/build/types.ts b/src/commands/build/types.ts index 587da620..5183a657 100644 --- a/src/commands/build/types.ts +++ b/src/commands/build/types.ts @@ -1,3 +1,4 @@ +import type { getRendererOptions } from "../../utils/progress.js"; import { UploadTo } from "../../releaseUploader/index.js"; import { CliGlobalOptions } from "../../types.js"; @@ -17,6 +18,4 @@ export interface BuildCommandOptions extends CliGlobalOptions { arch?: string; } -export interface VerbosityOptions { - renderer: "verbose" | "silent" | "default"; -} +export type VerbosityOptions = ReturnType; diff --git a/src/commands/build/variants.ts b/src/commands/build/variants.ts index f96799d3..853e029b 100644 --- a/src/commands/build/variants.ts +++ b/src/commands/build/variants.ts @@ -16,7 +16,6 @@ export function getPackagesToBuildProps({ variantsDirPath: string; composeFileName: string; }): PackageToBuildProps[] { - const buildVariantMapArgs = { rootDir, variantsDirPath, composeFileName }; if (!allVariants && !commaSeparatedVariants) @@ -34,7 +33,7 @@ export function getPackagesToBuildProps({ console.log( `${chalk.dim( - `Building package from template for variant(s) ${commaSeparatedVariants}...` + `Building package from template for variant(s) ${validVariantNames.join(", ")}...` )}` ); diff --git a/src/commands/githubActions/build/cleanPinsFromDeletedBranches.ts b/src/commands/githubActions/build/cleanPinsFromDeletedBranches.ts index 95ff8592..fca63313 100644 --- a/src/commands/githubActions/build/cleanPinsFromDeletedBranches.ts +++ b/src/commands/githubActions/build/cleanPinsFromDeletedBranches.ts @@ -1,3 +1,6 @@ +import path from "path"; +import { defaultVariantsDirName } from "../../../params.js"; +import { getAllVariantsInPath } from "../../../files/variants/getAllPackageVariants.js"; import { fetchPinsGroupedByBranch } from "../../../pinStrategy/index.js"; import { cliArgsToReleaseUploaderProvider } from "../../../releaseUploader/index.js"; import { Github } from "../../../providers/github/Github.js"; @@ -8,13 +11,26 @@ import { readManifest } from "../../../files/index.js"; * Removes all pins associated with a branch that no longer exists */ export async function cleanPinsFromDeletedBranches({ - dir + dir, + variantsDirName = defaultVariantsDirName }: { dir: string; + variantsDirName?: string; }): Promise { // Read manifest from disk to get package name const { manifest } = readManifest([{ dir }]); + const variantsPath = path.join(dir, variantsDirName); + const manifests = manifest.name + ? [manifest] + : getAllVariantsInPath(variantsPath).map( + variant => + readManifest([{ dir }, { dir: path.join(variantsPath, variant) }]) + .manifest + ); + if (manifests.some(item => !item.name)) + throw new Error("Cannot clean pins without a package name"); + // Connect to Github Octokit REST API to know existing branches const github = Github.fromLocal(dir); const branches = await github.listBranches(); @@ -28,17 +44,24 @@ export async function cleanPinsFromDeletedBranches({ throw Error("Must use pinata for deletePins"); const pinata = new PinataPinManager(releaseUploaderProvider); - const pinsGroupedByBranch = await fetchPinsGroupedByBranch(pinata, manifest); - for (const { branch, pins } of pinsGroupedByBranch) { - if (branches.find(b => b.name === branch)) continue; + for (const manifest of manifests) { + const pinsGroupedByBranch = await fetchPinsGroupedByBranch( + pinata, + manifest + ); + for (const { branch, pins } of pinsGroupedByBranch) { + if (branches.find(b => b.name === branch)) continue; + // A branch may have been created after the list was fetched. Fail closed. + if (await github.branchExists(branch)) continue; - // Branch not found, delete all associated pins - for (const pin of pins) { - console.log(`Unpin ${pin.commit} ${pin.ipfsHash}`); - await pinata.unpin(pin.ipfsHash).catch(e => { - // Don't prevent unpinning other pins if one is faulty - console.error(`Error on unpin ${pin.ipfsHash}`, e); - }); + // Branch not found, delete all associated pins + for (const pin of pins) { + console.log(`Unpin ${pin.commit} ${pin.ipfsHash}`); + await pinata.unpin(pin.ipfsHash).catch(e => { + // Don't prevent unpinning other pins if one is faulty + console.error(`Error on unpin ${pin.ipfsHash}`, e); + }); + } } } } diff --git a/src/commands/githubActions/build/index.ts b/src/commands/githubActions/build/index.ts index 0b34fae4..7c6c4953 100644 --- a/src/commands/githubActions/build/index.ts +++ b/src/commands/githubActions/build/index.ts @@ -1,6 +1,6 @@ import { CommandModule } from "yargs"; import { CliGlobalOptions } from "../../../types.js"; -import { defaultDir } from "../../../params.js"; +import { defaultDir, defaultVariantsDirName } from "../../../params.js"; import { getGithubContext } from "../../../providers/github/githubActions.js"; import { buildHandler } from "../../build/handler.js"; import { Github } from "../../../providers/github/Github.js"; @@ -30,6 +30,12 @@ export const gaBuild: CommandModule = { describe: "Build and upload test release and post a comment with install link to the triggering PR", builder: { + variants_dir_name: { + alias: "variants-dir-name", + type: "string", + default: defaultVariantsDirName, + description: "Directory containing package variants" + }, all_variants: { alias: "all-variants", description: `Build all package variants at once, by merging the dappnode_package.json and docker-compose.yml files in the root of the project with the specific ones defined for each package variant`, @@ -50,7 +56,9 @@ export const gaBuild: CommandModule = { async function gaBuildHandler({ dir = defaultDir, all_variants, - variants + variants, + variants_dir_name, + compose_file_name }: BuildActionOptions): Promise { const { eventName, sha: commitSha, ref: refString } = getGithubContext(); const ref = parseRef(refString); @@ -59,7 +67,10 @@ async function gaBuildHandler({ // Doing it here prevents having to add two workflows per repo. // Also, ensures that pins are deleted eventually, even if this fails sometimes try { - await cleanPinsFromDeletedBranches({ dir }); + await cleanPinsFromDeletedBranches({ + dir, + variantsDirName: variants_dir_name + }); } catch (e) { console.error("Error on cleanPinsFromDeletedBranches", e); } @@ -77,7 +88,9 @@ async function gaBuildHandler({ commitSha, branch: ref.branch, all_variants, - variants + variants, + variants_dir_name, + compose_file_name }); } else if (eventName === "push" || eventName === "pull_request") { // Consider that for 'pull_request' commitSha does not represent a known commit @@ -88,12 +101,15 @@ async function gaBuildHandler({ // By default just do a test build and skip_save await buildHandler({ + dir, provider: "dappnode", upload_to: "ipfs", skip_save: true, verbose: true, all_variants, - variants + variants, + variants_dir_name, + compose_file_name }); } else if (!eventName) { throw Error("Not in Github action context"); @@ -107,25 +123,32 @@ export async function buildAndComment({ commitSha, branch, all_variants, - variants + variants, + variants_dir_name, + compose_file_name }: { dir: string; commitSha: string; branch: string; all_variants?: boolean; variants?: string; + variants_dir_name?: string; + compose_file_name?: string; }): Promise { // Connect to Github Octokit REST API and post or edit a comment on PR const github = Github.fromLocal(dir); const buildResults = await buildHandler({ + dir, provider: "pinata", upload_to: "ipfs", require_git_data: true, delete_old_pins: true, verbose: true, all_variants, - variants + variants, + variants_dir_name, + compose_file_name }); const body = getBuildBotComment({ diff --git a/src/commands/githubActions/build/types.ts b/src/commands/githubActions/build/types.ts index 42b2dd61..d708e839 100644 --- a/src/commands/githubActions/build/types.ts +++ b/src/commands/githubActions/build/types.ts @@ -1,6 +1,7 @@ import { CliGlobalOptions } from "../../../types.js"; export interface BuildActionOptions extends CliGlobalOptions { - variants?: string; - all_variants?: boolean; + variants?: string; + variants_dir_name?: string; + all_variants?: boolean; } diff --git a/src/commands/githubActions/bumpUpstream/github/closeOldPrs.ts b/src/commands/githubActions/bumpUpstream/github/closeOldPrs.ts index c3b6c661..80a7970c 100644 --- a/src/commands/githubActions/bumpUpstream/github/closeOldPrs.ts +++ b/src/commands/githubActions/bumpUpstream/github/closeOldPrs.ts @@ -80,7 +80,7 @@ async function closePr( */ async function deleteBranch(branchName: string) { try { - await shell(`git push origin --delete ${branchName}`); + await shell(["git", "push", "origin", "--delete", branchName]); console.log(`Deleted branch: ${branchName}`); } catch (error) { console.error(`Error deleting branch ${branchName}`, error); diff --git a/src/commands/githubActions/bumpUpstream/github/isBranchNew.ts b/src/commands/githubActions/bumpUpstream/github/isBranchNew.ts index 734f2201..b2aa14bb 100644 --- a/src/commands/githubActions/bumpUpstream/github/isBranchNew.ts +++ b/src/commands/githubActions/bumpUpstream/github/isBranchNew.ts @@ -3,14 +3,16 @@ import { getLocalBranchExists } from "../../../../utils/git.js"; export async function isBranchNew({ branchName, - repo + repo, + dir }: { branchName: string; repo: Github; + dir?: string; }): Promise { const [remoteBranchExists, localBranchExists] = await Promise.all([ repo.branchExists(branchName), - getLocalBranchExists(branchName) + getLocalBranchExists(branchName, dir) ]); return !remoteBranchExists && !localBranchExists; diff --git a/src/commands/githubActions/bumpUpstream/github/isValidRelease.ts b/src/commands/githubActions/bumpUpstream/github/isValidRelease.ts index 3337c633..7d5d84b4 100644 --- a/src/commands/githubActions/bumpUpstream/github/isValidRelease.ts +++ b/src/commands/githubActions/bumpUpstream/github/isValidRelease.ts @@ -1,8 +1,12 @@ import semver from "semver"; export function isValidRelease(version: string): boolean { + // Commands receive tags as arguments, not shell source; this only rejects + // characters that can never form a branch name. `@` is used by real + // upstreams (e.g. n8n@2.46.6). + if (!/^[a-zA-Z0-9][a-zA-Z0-9._+/@-]*$/.test(version)) return false; // Nightly builds are not considered valid releases (not taken into account by semver) - if (version.includes("nightly")) return false; + if (version.toLowerCase().includes("nightly")) return false; if (semver.valid(version)) { const preReleases = semver.prerelease(version); diff --git a/src/commands/githubActions/bumpUpstream/index.ts b/src/commands/githubActions/bumpUpstream/index.ts index 8de15d1d..34d2d160 100644 --- a/src/commands/githubActions/bumpUpstream/index.ts +++ b/src/commands/githubActions/bumpUpstream/index.ts @@ -106,7 +106,7 @@ async function gaBumpUpstreamHandler({ const githubSettings = await getGithubSettings(dir, upstreamSettings); const { branchName, repo } = githubSettings; - if (!(await isBranchNew({ branchName, repo }))) { + if (!(await isBranchNew({ branchName, repo, dir }))) { // We assume the PR was already opened console.log(`Branch ${branchName} already exists`); return; @@ -129,6 +129,7 @@ async function gaBumpUpstreamHandler({ }); await prepareAndCommitChanges({ + dir, gitSettings, upstreamSettings, githubSettings @@ -145,8 +146,14 @@ async function gaBumpUpstreamHandler({ return; } - const gitHead = await getGitHead(); - await buildAndComment({ dir, commitSha: gitHead.commit, branch: branchName, all_variants: useVariants }); + const gitHead = await getGitHead(dir); + await buildAndComment({ + dir, + commitSha: gitHead.commit, + branch: branchName, + all_variants: useVariants, + variants_dir_name: variantsDir + }); } /** @@ -217,7 +224,7 @@ function updateManifestUpstreamVersion({ try { writeManifest(manifest, manifestFormat, { dir }); } catch (e) { - throw new Error(`Error writing manifest: ${e.message}`); + throw new Error(`Error writing manifest: ${e.message}`, { cause: e }); } } @@ -232,10 +239,11 @@ async function updateManifestPkgVersion({ allVariants?: boolean; variantsDir: string; }): Promise { + const variantsPath = path.resolve(dir, variantsDir); const manifestDirs = allVariants - ? getAllVariantsInPath(variantsDir).map(variant => - path.join(variantsDir, variant) - ) + ? getAllVariantsInPath(variantsPath).map(variant => + path.join(variantsPath, variant) + ) : [dir]; for (const dir of manifestDirs) { @@ -285,10 +293,12 @@ async function getNewManifestVersion({ } async function prepareAndCommitChanges({ + dir, gitSettings, upstreamSettings, githubSettings }: { + dir: string; gitSettings: GitSettings; upstreamSettings: UpstreamSettings[]; githubSettings: GithubSettings; @@ -303,9 +313,9 @@ async function prepareAndCommitChanges({ return; } - await configureGitUser(gitSettings); - await checkoutNewBranch(branchName); - await commitAndPushChanges({ commitMsg, branchRef }); + await configureGitUser(gitSettings, dir); + await checkoutNewBranch(branchName, dir); + await commitAndPushChanges({ commitMsg, branchRef, dir }); await attemptToOpenPR({ commitMsg, upstreamSettings, githubSettings }); } @@ -315,24 +325,38 @@ function createCommitMessage(upstreamSettings: UpstreamSettings[]): string { .join(", ")}`; } -async function configureGitUser({ userName, userEmail }: GitSettings) { - await shell(`git config user.name ${userName}`); - await shell(`git config user.email ${userEmail}`); +async function configureGitUser( + { userName, userEmail }: GitSettings, + dir: string +) { + await shell(["git", "config", "user.name", userName], { cwd: dir }); + await shell(["git", "config", "user.email", userEmail], { cwd: dir }); } -async function checkoutNewBranch(branchName: string) { - await shell(`git checkout -b ${branchName}`); +async function checkoutNewBranch(branchName: string, dir: string) { + await shell(["git", "check-ref-format", "--branch", branchName], { + cwd: dir + }); + await shell(["git", "checkout", "-b", branchName], { cwd: dir }); } async function commitAndPushChanges({ + dir, commitMsg, branchRef }: { + dir: string; commitMsg: string; branchRef: string; }) { - await shell(`git commit -a -m "${commitMsg}"`, { pipeToMain: true }); - await shell(`git push -u origin ${branchRef}`, { pipeToMain: true }); + await shell(["git", "commit", "-a", "-m", commitMsg], { + pipeToMain: true, + cwd: dir + }); + await shell(["git", "push", "-u", "origin", branchRef], { + pipeToMain: true, + cwd: dir + }); } async function attemptToOpenPR({ diff --git a/src/commands/init/fileOperations.ts b/src/commands/init/fileOperations.ts index 31cf4d4e..a5671796 100644 --- a/src/commands/init/fileOperations.ts +++ b/src/commands/init/fileOperations.ts @@ -47,7 +47,7 @@ export function createPackageDirectories( } } -export function writePackageFiles({ +export async function writePackageFiles({ dir, answers, useVariants, @@ -65,9 +65,9 @@ export function writePackageFiles({ rootCompose: Compose; composeFileName: string; serviceName: string; -}): void { +}): Promise { const rootManifestPath = getManifestPath(defaultManifestFormat, { dir }); - confirmManifestOverwrite(rootManifestPath, force); + await confirmManifestOverwrite(rootManifestPath, force); if (useVariants) writeMultiVariantPackageFiles({ @@ -88,7 +88,7 @@ export function writePackageFiles({ addDefaultAvatar(dir); - addDockerfile(dir); + addDockerfile(dir, force); addGitignore(dir); } @@ -107,7 +107,7 @@ function writeSinglePackageFiles({ writeManifest(rootManifest, defaultManifestFormat, { dir }); // Only write a compose if it doesn't exist - if (!fs.existsSync(getComposePath({ dir }))) { + if (!fs.existsSync(getComposePath({ dir, composeFileName }))) { writeCompose(rootCompose, { dir, composeFileName }); } } @@ -197,8 +197,10 @@ function addDefaultAvatar(dir: string) { } } -function addDockerfile(dir: string) { - fs.writeFileSync(path.join(dir, dockerfileName), dockerfileData); +function addDockerfile(dir: string, force: boolean) { + const dockerfilePath = path.join(dir, dockerfileName); + if (force || !fs.existsSync(dockerfilePath)) + fs.writeFileSync(dockerfilePath, dockerfileData); } /** diff --git a/src/commands/init/handler.ts b/src/commands/init/handler.ts index 3f22631b..b5814aaa 100644 --- a/src/commands/init/handler.ts +++ b/src/commands/init/handler.ts @@ -1,6 +1,6 @@ import { Manifest, Compose, getImageTag } from "@dappnode/types"; import { defaultDir, defaultComposeFileName } from "../../params.js"; -import { shell } from "../../utils/shell.js"; +import path from "path"; import { defaultVersion } from "./params.js"; import { InitCommandOptions, UserAnswers } from "./types.js"; import { getDnpName, getShortDnpName } from "./naming.js"; @@ -21,7 +21,7 @@ export async function initHandler({ const useDefaults = !!yes; // shell outputs tend to include trailing spaces and new lines - const directoryName = await shell('echo "${PWD##*/}"'); + const directoryName = path.basename(path.resolve(dir)); const defaultName = getDnpName(directoryName); const answers = await getUserAnswers({ @@ -43,7 +43,7 @@ export async function initHandler({ }); createPackageDirectories(dir, answers, useVariants); - writePackageFiles({ + await writePackageFiles({ dir, answers, useVariants, diff --git a/src/commands/init/naming.ts b/src/commands/init/naming.ts index 4e92cb90..fcf61c7f 100644 --- a/src/commands/init/naming.ts +++ b/src/commands/init/naming.ts @@ -54,5 +54,8 @@ export function getDnpName(name: string): string { name = name.toLowerCase(); // Append public domain - return name.endsWith(".eth") ? name : name + publicRepoDomain; + return name.endsWith(".eth") + ? name + : name.replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") + + publicRepoDomain; } diff --git a/src/commands/publish/handler.ts b/src/commands/publish/handler.ts index 27bd37d4..81c6c3c7 100644 --- a/src/commands/publish/handler.ts +++ b/src/commands/publish/handler.ts @@ -1,3 +1,4 @@ +import { getRendererOptions } from "../../utils/progress.js"; import Listr from "listr"; import path from "path"; import { @@ -43,10 +44,6 @@ export async function publishHandler({ const isCi = process.env.CI; - const verbosityOptions: VerbosityOptions = { - renderer: verbose ? "verbose" : silent ? "silent" : "default" - }; - /** * Specific set of options used for internal DAppNode releases. * Caution: options may change without notice. @@ -61,6 +58,11 @@ export async function publishHandler({ githubRelease = true; } + const verbosityOptions: VerbosityOptions = getRendererOptions({ + verbose, + silent + }); + const releaseType = parseReleaseType({ type }); const variantsDirPath = path.join(dir, variantsDirName); @@ -77,6 +79,7 @@ export async function publishHandler({ uploadTo, userTimeout, requireGitData, + deleteOldPins, developerAddress, githubRelease, verbosityOptions, diff --git a/src/dappnodesdk.ts b/src/dappnodesdk.ts index 17c7645c..e8219abe 100755 --- a/src/dappnodesdk.ts +++ b/src/dappnodesdk.ts @@ -3,6 +3,7 @@ import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import chalk from "chalk"; +import { formatCliError } from "./utils/formatCliError.js"; import figlet from "figlet"; import dotenv from "dotenv"; @@ -46,8 +47,9 @@ dappnodesdk.options({ alias: "debug", coerce: debug => { if (debug || process.env.DEBUG) { - // @ts-ignore - global.DEBUG_MODE = true; + ( + globalThis as typeof globalThis & { DEBUG_MODE?: boolean } + ).DEBUG_MODE = true; return true; } }, @@ -81,10 +83,25 @@ dappnodesdk.epilogue( /** * Handle errors */ +const reportedErrors = new WeakSet(); +function reportError(err: unknown): void { + process.exitCode = 1; + if (typeof err === "object" && err !== null) { + if (reportedErrors.has(err)) return; + reportedErrors.add(err); + } + const debug = Boolean( + (globalThis as typeof globalThis & { DEBUG_MODE?: boolean }).DEBUG_MODE + ); + console.error(`${formatCliError(err, { debug })}\n`); +} + dappnodesdk.fail((msg, err, yargs) => { + // Report once and exit with an error code. Rethrowing would make Node print the + // whole error object again (including the full command output and Listr context). + process.exitCode = 1; if (err) { - console.error(` ${chalk.red("✖")} ${err.message}\n`); - throw err; + reportError(err); } else { // If no specific error object is passed, use the message console.error(` ${chalk.red("✖")} ${msg}\n`); @@ -93,5 +110,6 @@ dappnodesdk.fail((msg, err, yargs) => { } }); -// Run CLI -dappnodesdk.parse(); +// Run CLI. yargs reports a failed async command through .fail() but still rejects +// the parse promise; handle it here so Node does not print the error a second time. +dappnodesdk.parseAsync().catch(reportError); diff --git a/src/files/compose/readCompose.ts b/src/files/compose/readCompose.ts index 94611422..6294295a 100644 --- a/src/files/compose/readCompose.ts +++ b/src/files/compose/readCompose.ts @@ -24,7 +24,7 @@ export function readCompose(paths?: ComposePaths[]): Compose { return merge({}, ...composes); } catch (e) { - throw Error(`Error parsing docker-compose: ${e.message}`); + throw new Error(`Error parsing docker-compose: ${e.message}`, { cause: e }); } } @@ -37,8 +37,8 @@ function loadCompose(paths?: ComposePaths): Compose { const data = readFile(composePath); const compose = yaml.load(data); - if (!compose || typeof compose === "string") + if (!compose || typeof compose !== "object" || Array.isArray(compose)) throw new Error(`Could not parse compose file: ${composePath}`); - return compose; + return compose as Compose; } diff --git a/src/files/manifest/compactManifestIfCore.ts b/src/files/manifest/compactManifestIfCore.ts index d7993693..8e4fa5e2 100644 --- a/src/files/manifest/compactManifestIfCore.ts +++ b/src/files/manifest/compactManifestIfCore.ts @@ -1,7 +1,4 @@ -import fs from "fs"; -import path from "path"; -import yaml from "js-yaml"; -import { SetupWizard, releaseFiles } from "@dappnode/types"; +import { readSetupWizardIfExists } from "../setupWizard/readSetupWizardIfExists.js"; import { readManifest } from "./readManifest.js"; import { writeManifest } from "./writeManifest.js"; @@ -16,26 +13,14 @@ import { writeManifest } from "./writeManifest.js"; * @param buildDir `build_0.1.0` */ export function compactManifestIfCore(buildDir: string): void { - const { manifest, format } = readManifest([{ dir: buildDir }]); + const { manifest, format } = readManifest([{ dir: buildDir }]); - if (manifest.type !== "dncore") return; + if (manifest.type !== "dncore") return; - const setupWizard = readSetupWizardIfExists(buildDir); - if (setupWizard) { - manifest.setupWizard = setupWizard; - } + const setupWizard = readSetupWizardIfExists([{ dir: buildDir }]); + if (setupWizard) { + manifest.setupWizard = setupWizard; + } - writeManifest(manifest, format, { dir: buildDir }); + writeManifest(manifest, format, { dir: buildDir }); } - -// Utils - -function readSetupWizardIfExists(buildDir: string): SetupWizard | null { - const files = fs.readdirSync(buildDir); - const setupWizardFile = files.find(file => - releaseFiles.setupWizard.regex.test(file) - ); - if (!setupWizardFile) return null; - const setupWizardPath = path.join(buildDir, setupWizardFile); - return yaml.load(fs.readFileSync(setupWizardPath, "utf8")); -} \ No newline at end of file diff --git a/src/files/manifest/getRepoSlugFromManifest.ts b/src/files/manifest/getRepoSlugFromManifest.ts index 363649cd..b5e146ab 100644 --- a/src/files/manifest/getRepoSlugFromManifest.ts +++ b/src/files/manifest/getRepoSlugFromManifest.ts @@ -2,18 +2,32 @@ import { readManifest } from "./readManifest.js"; import { ManifestPaths } from "./types.js"; /** - * Gets the repo slug from a manifest, using the repository property + * Gets the repo slug from a manifest, using the repository property. + * Accepts `https://github.com/owner/repo(.git)` and the npm-style `git+https://` form. * - * @returns repoSlug = "dappnode/DNP_ADMIN" + * @returns repoSlug = "dappnode/DNP_ADMIN", or "" if the repository is not on GitHub */ export function getRepoSlugFromManifest(paths: ManifestPaths): string { - const githubBaseUrl = "https://github.com/"; - const { manifest } = readManifest([paths]); const { type, url } = manifest.repository || {}; // Ignore faulty manifests - if (type !== "git" || !url || !url.includes(githubBaseUrl)) return ""; - // Get repo slug from the repoUrl, i.e. "https://github.com/dappnode/DNP_VPN" - const repoSlug = url.split(githubBaseUrl)[1] || ""; - return repoSlug.replace(/\/+$/, "").replace(".git", ""); + if (type !== "git" || !url) return ""; + return parseGithubRepoSlug(url); +} + +export function parseGithubRepoSlug(url: string): string { + let parsed: URL; + try { + parsed = new URL(url); + } catch { + return ""; + } + // Match the host exactly; a substring check would accept URLs that only mention github.com. + if (!["https:", "git+https:"].includes(parsed.protocol)) return ""; + if (parsed.hostname !== "github.com") return ""; + const [owner, repo] = parsed.pathname + .replace(/^\/+|\/+$/g, "") + .replace(/\.git$/, "") + .split("/"); + return owner && repo ? `${owner}/${repo}` : ""; } diff --git a/src/files/manifest/index.ts b/src/files/manifest/index.ts index 4afb6c06..d1ae474e 100644 --- a/src/files/manifest/index.ts +++ b/src/files/manifest/index.ts @@ -4,4 +4,4 @@ export { getRepoSlugFromManifest } from "./getRepoSlugFromManifest.js"; export { readManifest } from "./readManifest.js"; export { writeManifest } from "./writeManifest.js"; export { stringifyJson } from "./stringifyJson.js"; -export { ManifestFormat, ManifestPaths } from "./types.js"; +export { ManifestFormat, type ManifestPaths } from "./types.js"; diff --git a/src/files/manifest/readManifest.ts b/src/files/manifest/readManifest.ts index 8cfcf91f..71e51f48 100644 --- a/src/files/manifest/readManifest.ts +++ b/src/files/manifest/readManifest.ts @@ -19,11 +19,13 @@ import { merge } from "lodash-es"; * @throws {Error} - Throws an error if any manifest is not in JSON format, or if there is a * problem reading or parsing the manifests. */ -export function readManifest( - paths?: ManifestPaths[] -): { manifest: Manifest; format: ManifestFormat } { +export function readManifest(paths?: ManifestPaths[]): { + manifest: Manifest; + format: ManifestFormat; +} { try { - if (!paths) return loadManifest(); // Load default manifest + if (!paths || paths.length === 0) return loadManifest(); + if (paths.length === 1) return loadManifest(paths[0]); // Load default manifest const manifestsSpecs = paths.map(path => loadManifest(path)); @@ -47,16 +49,17 @@ export function readManifest( manifest: mergedManifest }; } catch (e) { - throw new Error(`Error parsing manifest: ${e.message}`); + throw new Error(`Error parsing manifest: ${e.message}`, { cause: e }); } } /** * Loads a manifest from the specified path. */ -function loadManifest( - paths?: ManifestPaths -): { manifest: Manifest; format: ManifestFormat } { +function loadManifest(paths?: ManifestPaths): { + manifest: Manifest; + format: ManifestFormat; +} { const manifestPath = findManifestPath(paths); const format = parseFormat(manifestPath); const data = readFile(manifestPath); @@ -65,16 +68,22 @@ function loadManifest( try { parsedData = yaml.load(data); } catch (e) { - throw new Error(`Error parsing manifest at ${manifestPath}: ${e.message}`); + throw new Error(`Error parsing manifest at ${manifestPath}: ${e.message}`, { + cause: e + }); } - if (!parsedData) { + if ( + !parsedData || + typeof parsedData !== "object" || + Array.isArray(parsedData) + ) { throw new Error(`Manifest at ${manifestPath} is empty or invalid.`); } return { format, - manifest: parsedData + manifest: parsedData as Manifest }; } @@ -100,8 +109,8 @@ function findManifestPath(paths?: ManifestPaths): string { } function parseFormat(filepath: string): ManifestFormat { - if (/.json$/.test(filepath)) return ManifestFormat.json; - if (/.yml$/.test(filepath)) return ManifestFormat.yml; - if (/.yaml$/.test(filepath)) return ManifestFormat.yaml; + if (/\.json$/.test(filepath)) return ManifestFormat.json; + if (/\.yml$/.test(filepath)) return ManifestFormat.yml; + if (/\.yaml$/.test(filepath)) return ManifestFormat.yaml; throw Error(`Unsupported manifest format: ${filepath}`); } diff --git a/src/files/notifications/index.ts b/src/files/notifications/index.ts index fcc72343..0bb88ddf 100644 --- a/src/files/notifications/index.ts +++ b/src/files/notifications/index.ts @@ -1,2 +1,2 @@ export { readNotificationsIfExists } from "./readNotificationsIfExists.js"; -export { NotificationsFormat, NotificationsPaths } from "./types.js"; +export { NotificationsFormat, type NotificationsPaths } from "./types.js"; diff --git a/src/files/notifications/readNotificationsIfExists.ts b/src/files/notifications/readNotificationsIfExists.ts index 838476fb..27098978 100644 --- a/src/files/notifications/readNotificationsIfExists.ts +++ b/src/files/notifications/readNotificationsIfExists.ts @@ -4,7 +4,7 @@ import yaml from "js-yaml"; import { defaultDir } from "../../params.js"; import { readFile } from "../../utils/file.js"; import { NotificationsConfig, releaseFiles } from "@dappnode/types"; -import { merge } from "lodash-es"; +import { mergeReplacingArrays } from "../../utils/merge.js"; import { NotificationsPaths } from "./types.js"; /** @@ -45,9 +45,22 @@ export function readNotificationsIfExists( }); // Merge all configurations - return merge({}, ...configs); + const merged = mergeReplacingArrays>(...configs); + for (const key of ["endpoints", "customEndpoints"] as const) { + const endpoints = new Map< + string, + NonNullable[number] + >(); + for (const config of configs) + for (const endpoint of config[key] || []) { + const id = endpoint.correlationId || endpoint.name; + endpoints.set(id, mergeReplacingArrays(endpoints.get(id), endpoint)); + } + if (endpoints.size > 0) merged[key] = [...endpoints.values()]; + } + return merged as NotificationsConfig; } catch (e) { - throw new Error(`Error parsing notifications: ${e.message}`); + throw new Error(`Error parsing notifications: ${e.message}`, { cause: e }); } } diff --git a/src/files/setupWizard/index.ts b/src/files/setupWizard/index.ts index 396c69e4..97cf59cc 100644 --- a/src/files/setupWizard/index.ts +++ b/src/files/setupWizard/index.ts @@ -1,2 +1,2 @@ export { readSetupWizardIfExists } from "./readSetupWizardIfExists.js"; -export { SetupWizardFormat, SetupWizardPaths } from "./types.js"; +export { SetupWizardFormat, type SetupWizardPaths } from "./types.js"; diff --git a/src/files/setupWizard/readSetupWizardIfExists.ts b/src/files/setupWizard/readSetupWizardIfExists.ts index ae1ea4d3..d9772f15 100644 --- a/src/files/setupWizard/readSetupWizardIfExists.ts +++ b/src/files/setupWizard/readSetupWizardIfExists.ts @@ -1,17 +1,17 @@ import fs from "fs"; import path from "path"; import yaml from "js-yaml"; -import { merge } from "lodash-es"; +import { mergeReplacingArrays } from "../../utils/merge.js"; import { defaultDir } from "../../params.js"; import { readFile } from "../../utils/file.js"; import { SetupWizard, releaseFiles } from "@dappnode/types"; import { SetupWizardPaths } from "./types.js"; /** - * Reads one or multiple setup-wizard YAML files and merges them. Returns null if none exist. + * Reads one or multiple setup-wizard JSON or YAML files and merges them. Returns null if none exist. * @param {SetupWizardPaths[]} paths - Optional array of directory/file specs. * @returns {SetupWizard | null} - * @throws {Error} Throws if parsing fails or non-YAML format is encountered. + * @throws {Error} Throws if parsing fails or unsupported format is encountered. */ export function readSetupWizardIfExists( paths?: SetupWizardPaths[] @@ -33,10 +33,10 @@ export function readSetupWizardIfExists( if (filePaths.length === 0) return null; - // Load and validate YAML-only files + // JSON is also valid YAML; preserve both supported source formats. const wizards = filePaths.map(fp => { - if (!/\.(yml|yaml)$/i.test(fp)) - throw new Error("Only YAML format supported for setup-wizard: " + fp); + if (!/\.(json|yml|yaml)$/i.test(fp)) + throw new Error("Expected JSON or YAML setup-wizard: " + fp); const data = readFile(fp); const parsed = yaml.load(data); if (!parsed || typeof parsed === "string") @@ -45,9 +45,19 @@ export function readSetupWizardIfExists( }); // Merge all specs - return merge({}, ...wizards); + const fields = new Map(); + for (const wizard of wizards) { + if (wizard.fields !== undefined && !Array.isArray(wizard.fields)) + throw new Error("setup-wizard.fields must be an array"); + for (const field of wizard.fields || []) + fields.set(field.id, mergeReplacingArrays(fields.get(field.id), field)); + } + return { + ...mergeReplacingArrays(...wizards), + fields: [...fields.values()] + }; } catch (e) { - throw new Error(`Error parsing setup-wizard: ${e.message}`); + throw new Error(`Error parsing setup-wizard: ${e.message}`, { cause: e }); } } diff --git a/src/pinStrategy/index.ts b/src/pinStrategy/index.ts index 8641fe3a..0ba2f5ef 100644 --- a/src/pinStrategy/index.ts +++ b/src/pinStrategy/index.ts @@ -1,6 +1,7 @@ import { PinataMetadata } from "../releaseUploader/pinata/index.js"; import { PinataPinManager } from "../providers/pinata/pinManager.js"; import { GitHead } from "../utils/git.js"; +import { shell } from "../utils/shell.js"; import { prettyPinataPinName } from "../utils/format.js"; import { DnpPinMetadata, PinDataSummary, PinsByBranch } from "./types.js"; import { groupPinsByBranch } from "./utils.js"; @@ -79,8 +80,72 @@ export async function fetchPinsGroupedByBranch( export async function fetchPinsWithBranchToDelete( pinata: PinataPinManager, manifest: Manifest, - gitHead: GitHead + gitHead: GitHead, + dir?: string ): Promise { const pins = await fetchPinsWithBranch(pinata, manifest, gitHead); - return pins.filter(pin => pin.commit && pin.commit !== gitHead.commit); + const candidates = pins.filter( + pin => + pin.commit && + pin.commit !== gitHead.commit && + /^[a-f0-9]{7,64}$/i.test(pin.commit) + ); + const ancestorOf = (commit: string) => + isAncestorCommit(commit, gitHead.commit, dir); + + let results = await Promise.all( + candidates.map(pin => ancestorOf(pin.commit as string)) + ); + // CI checkouts are usually shallow (depth 1), so older pin commits are unknown locally. + // Fetch the missing history once and re-check only the unresolved commits. + if (results.includes("unknown") && (await deepenShallowHistory(dir))) + results = await Promise.all( + candidates.map((pin, index) => + results[index] === "unknown" + ? ancestorOf(pin.commit as string) + : results[index] + ) + ); + // A commit that is still unknown (rewritten, foreign or unfetchable) must never cause an unpin. + return candidates.filter((pin, index) => results[index] === "ancestor"); +} + +type AncestryResult = "ancestor" | "not-ancestor" | "unknown"; + +/** `git merge-base --is-ancestor` exits 0 (yes), 1 (no) or 128 (unknown object). */ +async function isAncestorCommit( + commit: string, + head: string, + dir?: string +): Promise { + try { + await shell(["git", "merge-base", "--is-ancestor", commit, head], { + cwd: dir + }); + return "ancestor"; + } catch (e) { + return e.code === 1 ? "not-ancestor" : "unknown"; + } +} + +/** Returns true if the repository was shallow and its full history was fetched. */ +async function deepenShallowHistory(dir?: string): Promise { + try { + const shallow = await shell( + ["git", "rev-parse", "--is-shallow-repository"], + { cwd: dir } + ); + if (shallow.trim() !== "true") return false; + await shell( + ["git", "fetch", "--unshallow", "--no-tags", "--quiet", "origin"], + { + cwd: dir, + timeout: 10 * 60 * 1000 + } + ); + return true; + } catch (e) { + console.warn(`Could not fetch git history to check old pins: ${e.message}`); + return false; + } } diff --git a/src/pinStrategy/types.ts b/src/pinStrategy/types.ts index aebccdac..704d34ea 100644 --- a/src/pinStrategy/types.ts +++ b/src/pinStrategy/types.ts @@ -4,7 +4,8 @@ export interface DnpPinMetadata { dnpName: string; version: string; - upstreamVersion: string | undefined | string[]; + upstreamVersion: string | undefined; + [key: string]: string | undefined; commit: string | undefined; branch: string | undefined; } diff --git a/src/providers/apm/ApmRepository.ts b/src/providers/apm/ApmRepository.ts new file mode 100644 index 00000000..1c882f56 --- /dev/null +++ b/src/providers/apm/ApmRepository.ts @@ -0,0 +1,44 @@ +import { + Contract, + JsonRpcProvider, + toUtf8String, + type Provider, + isValidName +} from "ethers"; +import repoAbi from "../../contracts/RepoAbi.json" with { type: "json" }; + +/** The SDK only needs ENS resolution and the latest published APM version. */ +export class ApmRepository { + private readonly provider: Provider; + + constructor(ethereumUrl: string, provider?: Provider) { + if (!ethereumUrl) throw new Error("Ethereum URL is required"); + this.provider = + provider || + new JsonRpcProvider(ethereumUrl, "mainnet", { staticNetwork: true }); + } + + async getRepoContract(name: string): Promise { + if (!isValidName(name) || !name.endsWith(".dappnode.eth")) + throw new Error(`Invalid Dappnode ENS name: ${name}`); + const address = await this.provider.resolveName(name); + if (!address) throw new Error(`Could not resolve name ${name}: NOREPO`); + return new Contract(address, repoAbi, this.provider); + } + + async getVersionAndIpfsHash({ + dnpNameOrHash + }: { + dnpNameOrHash: string; + }): Promise<{ version: string; contentUri: string }> { + const repo = await this.getRepoContract(dnpNameOrHash); + const result = await repo.getFunction("getLatest").staticCall(); + const version: unknown = result[0]; + if (!Array.isArray(version) || version.length !== 3) + throw new Error(`Invalid APM semantic version for ${dnpNameOrHash}`); + return { + version: version.map(part => String(part)).join("."), + contentUri: toUtf8String(result[2]) + }; + } +} diff --git a/src/providers/github/Github.ts b/src/providers/github/Github.ts index a6cbd1ee..12a125e1 100644 --- a/src/providers/github/Github.ts +++ b/src/providers/github/Github.ts @@ -46,7 +46,6 @@ export class Github { return `${this.owner}/${this.repo}`; } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async getRepo() { try { const repoResponse = await this.octokit.rest.repos.get({ @@ -60,7 +59,7 @@ export class Github { return repoResponse.data; } catch (e) { if (e instanceof RequestError && e.status === 404) { - throw new Error(`Repo does not exist: ${this.repoSlug}`); + throw new Error(`Repo does not exist: ${this.repoSlug}`, { cause: e }); } e.message = `Error verifying repo ${this.repoSlug}: ${e.message}`; @@ -100,7 +99,8 @@ export class Github { } }); - if (matchingTags.data.length > 0) return true; + if (matchingTags.data.some(item => item.ref === `refs/tags/${tag}`)) + return true; return false; } catch (e) { @@ -131,17 +131,14 @@ export class Github { } } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async listReleases() { - return await this.octokit.rest.repos - .listReleases({ - owner: this.owner, - repo: this.repo, - headers: { - "X-GitHub-Api-Version": "2022-11-28" - } - }) - .then(res => res.data); + return await this.octokit.paginate(this.octokit.rest.repos.listReleases, { + owner: this.owner, + repo: this.repo, + headers: { + "X-GitHub-Api-Version": "2022-11-28" + } + }); } /** @@ -238,21 +235,48 @@ export class Github { const filepath = path.resolve(assetsDir, file); const contentType = mime.lookup(filepath) || "application/octet-stream"; + const name = `${fileNamePrefix || ""}${path.basename(filepath)}`; + const size = fs.statSync(filepath).size; try { // The uploadReleaseAssetApi fails sometimes, retry 3 times await retry( async () => { - await this.octokit.repos.uploadReleaseAsset({ - owner: this.owner, - repo: this.repo, - release_id: releaseId, - data: fs.createReadStream(filepath) as any, - headers: { - "content-type": contentType, - "content-length": fs.statSync(filepath).size - }, - name: `${fileNamePrefix || ""}${path.basename(filepath)}` - }); + // One stream per attempt. A read error fails the request that consumes it; + // the listener and destroy() stop a stream left over by a failed attempt from + // keeping the file open or raising an unhandled 'error' event later. + const data = fs.createReadStream(filepath); + data.on("error", () => {}); + try { + await this.octokit.request({ + method: "POST", + url: "https://uploads.github.com/repos/{owner}/{repo}/releases/{release_id}/assets{?name}", + owner: this.owner, + repo: this.repo, + release_id: releaseId, + data, + headers: { + "content-type": contentType, + "content-length": size + }, + name + }); + } catch (e) { + // A failed attempt may still have stored the asset; the retry then gets 422. + if (!isAssetAlreadyExistsError(e)) throw e; + const existing = await this.findReleaseAsset(releaseId, name); + if (existing?.state === "uploaded" && existing.size === size) + return; + // Partial or different asset: remove it so the next attempt can upload. + if (existing) + await this.octokit.rest.repos.deleteReleaseAsset({ + owner: this.owner, + repo: this.repo, + asset_id: existing.id + }); + throw e; + } finally { + data.destroy(); + } }, { retries: 3 } ); @@ -263,6 +287,19 @@ export class Github { } } + private async findReleaseAsset(releaseId: number, name: string) { + const assets = await this.octokit.paginate( + this.octokit.rest.repos.listReleaseAssets, + { + owner: this.owner, + repo: this.repo, + release_id: releaseId, + per_page: 100 + } + ); + return assets.find(asset => asset.name === name); + } + /** * Receives a tag and returns a prettified release name * @@ -392,7 +429,6 @@ export class Github { * Returns open PRs where head branch equals `branch` * Only branches and PRs originating from the same repo */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async getOpenPrsFromBranch(branch: string) { const openPrsResponse = await this.octokit.rest.pulls.list({ owner: this.owner, @@ -408,7 +444,7 @@ export class Github { } /** - * Returns list of branches, limited to 100. For more implement pagination + * Returns all branches; cleanup must never infer deletion from a partial page. * @returns branch = { * name: "octocat-patch-1" * commit: { @@ -416,23 +452,20 @@ export class Github { * } * } */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async listBranches() { - const branchesResponse = await this.octokit.rest.repos.listBranches({ + return await this.octokit.paginate(this.octokit.rest.repos.listBranches, { owner: this.owner, repo: this.repo, + per_page: 100, headers: { "X-GitHub-Api-Version": "2022-11-28" } }); - - return branchesResponse.data; } /** * @param branch "octocat-patch-1" */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types async getBranch(branch: string) { const branchResponse = await this.octokit.rest.repos.getBranch({ owner: this.owner, @@ -482,3 +515,11 @@ export class Github { } } } + +function isAssetAlreadyExistsError(e: unknown): boolean { + const error = e as { status?: number; response?: { data?: unknown } }; + return ( + error?.status === 422 && + JSON.stringify(error.response?.data ?? "").includes("already_exists") + ); +} diff --git a/src/providers/github/githubActions.ts b/src/providers/github/githubActions.ts index 119ba01c..f7e3e504 100644 --- a/src/providers/github/githubActions.ts +++ b/src/providers/github/githubActions.ts @@ -4,7 +4,6 @@ import fs from "fs"; * Returns Github Actions context. * From https://github.com/actions/toolkit/blob/c861dd8859fe5294289fcada363ce9bc71e9d260/packages/github/src/context.ts#L25 */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function getGithubContext() { return { // The name of the webhook event that triggered the workflow. diff --git a/src/providers/pinata/pinManager.ts b/src/providers/pinata/pinManager.ts index 093dfec8..63de1335 100644 --- a/src/providers/pinata/pinManager.ts +++ b/src/providers/pinata/pinManager.ts @@ -51,24 +51,32 @@ export class PinataPinManager { // Fetch only "pinned" items by default searchParams["status"] = filters?.status || "pinned"; - // Note: Results in rows will be limited to 1000, in case of needing more pagination should be implemented try { - const result: { - count: number; - rows: PinItem[]; - } = await got - .get({ - prefixUrl: this.pinataUrl, - url: "data/pinList", - headers: { - pinata_api_key: this.apiKey, - pinata_secret_api_key: this.secretApiKey - }, - searchParams - }) - .json(); + const pins: PinItem[] = []; + while (true) { + const result: { + count: number; + rows: PinItem[]; + } = await got + .get({ + prefixUrl: this.pinataUrl, + url: "data/pinList", + headers: { + pinata_api_key: this.apiKey, + pinata_secret_api_key: this.secretApiKey + }, + searchParams: { + ...searchParams, + pageLimit: "1000", + pageOffset: String(pins.length) + } + }) + .json(); - return result.rows; + pins.push(...result.rows); + if (result.rows.length === 0 || pins.length >= result.count) + return pins; + } } catch (e) { e.message = `Error on Pinata pinList: ${e.message}`; throw e; diff --git a/src/releaseUploader/interface.ts b/src/releaseUploader/interface.ts index 40097035..e78b1e6e 100644 --- a/src/releaseUploader/interface.ts +++ b/src/releaseUploader/interface.ts @@ -15,6 +15,7 @@ export interface IReleaseUploader { dirPath: string; metadata: PinataMetadata; onProgress?: (percent: number) => void; + onUploadComplete?: () => void; }): Promise; /** diff --git a/src/releaseUploader/ipfsNode/addDirFromUrls.ts b/src/releaseUploader/ipfsNode/addDirFromUrls.ts index 66b5757d..316caf46 100644 --- a/src/releaseUploader/ipfsNode/addDirFromUrls.ts +++ b/src/releaseUploader/ipfsNode/addDirFromUrls.ts @@ -1,6 +1,7 @@ -import { got } from "got"; +import { got, type Request } from "got"; +import { uploadTimeout } from "../utils/uploadTimeout.js"; import FormData from "form-data"; -import request from "request"; +import { PassThrough } from "stream"; import { normalizeIpfsProvider } from "./ipfsProvider.js"; /** @@ -18,9 +19,10 @@ export async function ipfsAddDirFromUrls( // Create form and append all files recursively const form = new FormData(); + const streams: Request[] = []; for (const { filepath, url } of files) { - // Using request instead of got, because got doesn't seem to work - const fileStream = request(url); + const fileStream = got.stream(url, { retry: { limit: 0 } }); + streams.push(fileStream); fileStream.on("data", chunk => { if (onProgress) onProgress(filepath, chunk.length); }); @@ -28,15 +30,26 @@ export async function ipfsAddDirFromUrls( } // Parse the ipfsProvider the a full base apiUrl - const res = await got({ + const body = new PassThrough(); + form.on("error", error => body.destroy(error)); + const upload = got({ prefixUrl: normalizeIpfsProvider(ipfsProvider), url: "api/v0/add", method: "POST", headers: form.getHeaders(), - body: form, + body, + timeout: uploadTimeout, + retry: { limit: 0 }, http2: true }); + form.pipe(body); + const res = await upload.finally(() => { + for (const stream of streams) stream.destroy(); + form.destroy(); + body.destroy(); + }); + // res.body = '{"Name":"dir/file","Hash":"Qm...","Size":"2203"}\n{"Name":"dir","Hash":"Qm...","Size":"24622"}\n' // Trim last \n, split entries by \n and then select the last which is the root directory const lastFileUnparsed = res.body.trim().split("\n").slice(-1)[0]; diff --git a/src/releaseUploader/ipfsNode/addFromFs.ts b/src/releaseUploader/ipfsNode/addFromFs.ts index 1a338db3..ee8c06ba 100644 --- a/src/releaseUploader/ipfsNode/addFromFs.ts +++ b/src/releaseUploader/ipfsNode/addFromFs.ts @@ -1,4 +1,5 @@ import { got } from "got"; +import { uploadTimeout } from "../utils/uploadTimeout.js"; import { normalizeIpfsProvider } from "./ipfsProvider.js"; import { getFormDataFileUpload } from "../utils/formDataFileUpload.js"; @@ -12,7 +13,8 @@ import { getFormDataFileUpload } from "../utils/formDataFileUpload.js"; export async function ipfsAddFromFs( dirOrFilePath: string, ipfsProvider: string, - onProgress?: (percent: number) => void + onProgress?: (percent: number) => void, + onUploadComplete?: () => void ): Promise { // Create form and append all files recursively const form = getFormDataFileUpload(dirOrFilePath); @@ -26,6 +28,8 @@ export async function ipfsAddFromFs( method: "POST", headers: form.getHeaders(), body: form, + timeout: uploadTimeout, + retry: { limit: 0 }, http2: true }).on("uploadProgress", progress => { // Report upload progress, and throttle to one update per percent point @@ -35,6 +39,7 @@ export async function ipfsAddFromFs( lastPercent = currentRoundPercent; if (onProgress) onProgress(progress.percent); } + if (progress.percent === 1) onUploadComplete?.(); }); // res.body = '{"Name":"dir/file","Hash":"Qm...","Size":"2203"}\n{"Name":"dir","Hash":"Qm...","Size":"24622"}\n' diff --git a/src/releaseUploader/ipfsNode/index.ts b/src/releaseUploader/ipfsNode/index.ts index 5dd655ec..0ae1f28c 100644 --- a/src/releaseUploader/ipfsNode/index.ts +++ b/src/releaseUploader/ipfsNode/index.ts @@ -12,12 +12,19 @@ export class ReleaseUploaderIpfsNode implements IReleaseUploader { async addFromFs({ dirPath, - onProgress + onProgress, + onUploadComplete }: { dirPath: string; onProgress?: (percent: number) => void; + onUploadComplete?: () => void; }): Promise { - return await ipfsAddFromFs(dirPath, this.ipfsProvider, onProgress); + return await ipfsAddFromFs( + dirPath, + this.ipfsProvider, + onProgress, + onUploadComplete + ); } async testConnection(): Promise { diff --git a/src/releaseUploader/pinata/addDirFromFs.ts b/src/releaseUploader/pinata/addDirFromFs.ts index 5e9c0cab..d8f5263a 100644 --- a/src/releaseUploader/pinata/addDirFromFs.ts +++ b/src/releaseUploader/pinata/addDirFromFs.ts @@ -1,4 +1,5 @@ import { got } from "got"; +import { uploadTimeout } from "../utils/uploadTimeout.js"; import { getFormDataFileUpload } from "../utils/formDataFileUpload.js"; import { PinataMetadata, @@ -19,7 +20,8 @@ export async function pinataAddFromFs({ pinataMetadata, pinataOptions, credentials, - onProgress + onProgress, + onUploadComplete }: { dirOrFilePath: string; pinataUrl: string; @@ -27,6 +29,7 @@ export async function pinataAddFromFs({ pinataMetadata?: PinataMetadata; pinataOptions?: PinataOptions; onProgress?: (percent: number) => void; + onUploadComplete?: () => void; }): Promise { // Create form and append all files recursively const form = getFormDataFileUpload(dirOrFilePath); @@ -45,7 +48,9 @@ export async function pinataAddFromFs({ pinata_secret_api_key: credentials.secretApiKey }), body: form, - responseType: "json" + responseType: "json", + timeout: uploadTimeout, + retry: { limit: 0 } }).on("uploadProgress", progress => { // Report upload progress, and throttle to one update per percent point // { percent: 0.9995998225975282, transferred: 733675762, total: 733969480 } @@ -54,6 +59,7 @@ export async function pinataAddFromFs({ lastPercent = currentRoundPercent; if (onProgress) onProgress(progress.percent); } + if (progress.percent === 1) onUploadComplete?.(); }); const uploadData = response.body as IpfsUploadResult; diff --git a/src/releaseUploader/pinata/index.ts b/src/releaseUploader/pinata/index.ts index 09755972..dc299d03 100644 --- a/src/releaseUploader/pinata/index.ts +++ b/src/releaseUploader/pinata/index.ts @@ -25,18 +25,21 @@ export class ReleaseUploaderIpfsPinata implements IReleaseUploader { async addFromFs({ dirPath, metadata, - onProgress + onProgress, + onUploadComplete }: { dirPath: string; metadata: PinataMetadata; onProgress?: (percent: number) => void; + onUploadComplete?: () => void; }): Promise { return await pinataAddFromFs({ dirOrFilePath: dirPath, pinataUrl: this.pinataUrl, pinataMetadata: metadata, credentials: { apiKey: this.apiKey, secretApiKey: this.secretApiKey }, - onProgress + onProgress, + onUploadComplete }); } diff --git a/src/releaseUploader/swarmNode/addDirFromFs.ts b/src/releaseUploader/swarmNode/addDirFromFs.ts index 31be3761..bc21c49c 100644 --- a/src/releaseUploader/swarmNode/addDirFromFs.ts +++ b/src/releaseUploader/swarmNode/addDirFromFs.ts @@ -1,4 +1,5 @@ import tarFS from "tar-fs"; +import { uploadTimeout } from "../utils/uploadTimeout.js"; import { got } from "got"; /** @@ -7,18 +8,22 @@ import { got } from "got"; export async function swarmAddDirFromFs( dirPath: string, gatewayUrl: string, - onProgress?: (percent: number) => void + onProgress?: (percent: number) => void, + onUploadComplete?: () => void ): Promise { const res = await got({ prefixUrl: gatewayUrl, - url: "/bzz:/", + url: "bzz:/", method: "POST", headers: { "content-type": "application/x-tar" }, - body: tarFS.pack(dirPath) + body: tarFS.pack(dirPath), + timeout: uploadTimeout, + retry: { limit: 0 } }).on("uploadProgress", progress => { // Report upload progress // { percent: 0.9995998225975282, transferred: 733675762, total: 733969480 } if (onProgress) onProgress(progress.percent); + if (progress.percent === 1) onUploadComplete?.(); }); const rootHash = res.body; diff --git a/src/releaseUploader/swarmNode/index.ts b/src/releaseUploader/swarmNode/index.ts index 9975c2ca..2eb11519 100644 --- a/src/releaseUploader/swarmNode/index.ts +++ b/src/releaseUploader/swarmNode/index.ts @@ -12,12 +12,19 @@ export class ReleaseUploaderSwarmNode implements IReleaseUploader { async addFromFs({ dirPath, - onProgress + onProgress, + onUploadComplete }: { dirPath: string; onProgress?: (percent: number) => void; + onUploadComplete?: () => void; }): Promise { - return await swarmAddDirFromFs(dirPath, this.gatewayUrl, onProgress); + return await swarmAddDirFromFs( + dirPath, + this.gatewayUrl, + onProgress, + onUploadComplete + ); } async testConnection(): Promise { diff --git a/src/releaseUploader/utils/uploadTimeout.ts b/src/releaseUploader/utils/uploadTimeout.ts new file mode 100644 index 00000000..66e363c1 --- /dev/null +++ b/src/releaseUploader/utils/uploadTimeout.ts @@ -0,0 +1,7 @@ +/** + * Upload requests abort only when the connection stops moving. + * A total limit would fail healthy large uploads on slow links + * (a ~1.6 GB release needs over 3.6 Mbit/s to finish within an hour). + * The idle window also covers the server hashing/pinning after the last byte. + */ +export const uploadTimeout = { socket: 15 * 60 * 1000 } as const; diff --git a/src/tasks/buildAndUpload/buildWithBuildx.ts b/src/tasks/buildAndUpload/buildWithBuildx.ts index f6c4d807..1e45c563 100644 --- a/src/tasks/buildAndUpload/buildWithBuildx.ts +++ b/src/tasks/buildAndUpload/buildWithBuildx.ts @@ -1,3 +1,5 @@ +import fs from "fs"; +import { taskLog } from "../../utils/progress.js"; import { ListrTask } from "listr"; import semver from "semver"; import { shell } from "../../utils/shell.js"; @@ -67,40 +69,61 @@ export function buildWithBuildx({ switch (architecture) { case "linux/arm64": - await shell( - `docker run --privileged --rm tonistiigi/binfmt --uninstall qemu-*` - ); - await shell( - `docker run --privileged --rm tonistiigi/binfmt --install all` - ); + await shell([ + "docker", + "run", + "--privileged", + "--rm", + "tonistiigi/binfmt", + "--uninstall", + "qemu-*" + ]); + await shell([ + "docker", + "run", + "--privileged", + "--rm", + "tonistiigi/binfmt", + "--install", + "all" + ]); // Make sure QEMU is enabled // `cat /proc/sys/fs/binfmt_misc/qemu-aarch64` break; } - const currentInstances = await shell(`docker buildx ls`); + const currentInstances = await shell(["docker", "buildx", "ls"]); if (currentInstances.includes(buildxInstanceName)) { - await shell(`docker buildx use ${buildxInstanceName}`); + await shell(["docker", "buildx", "use", buildxInstanceName]); } else { - await shell( - `docker buildx create --name ${buildxInstanceName} --use` - ); + await shell([ + "docker", + "buildx", + "create", + "--name", + buildxInstanceName, + "--use" + ]); } // Will build all services defined in the compose in paralel // The resulting images will be imported to docker with the tag declared in the service await shell( [ - "docker buildx bake", - "--progress plain", + "docker", + "buildx", + "bake", + "--progress", + "plain", "--load", - `--file ${tmpComposePath}`, + "--file", + tmpComposePath, `--set=*.platform=${architecture}` - ].join(" "), + ], { timeout: buildTimeout, maxBuffer: 100 * 1e6, - onData: data => (task.output = data) + onData: taskLog(task) } ); @@ -110,9 +133,15 @@ export function buildWithBuildx({ // Make sure the built was done for the correct architecture switch (architecture) { case "linux/arm64": { - const res = await shell( - `docker run --rm --entrypoint="" ${firstImageTag} uname -m` - ).catch(() => { + const res = await shell([ + "docker", + "run", + "--rm", + "--entrypoint=", + firstImageTag, + "uname", + "-m" + ]).catch(() => { // Ignore all errors }); if (res && res !== "aarch64") @@ -134,7 +163,7 @@ export function buildWithBuildx({ }), { title: "Cleanup temporary files", - task: async () => shell(`rm ${tmpComposePath}`) + task: async () => fs.promises.rm(tmpComposePath, { force: true }) } ]; } diff --git a/src/tasks/buildAndUpload/buildWithCompose.ts b/src/tasks/buildAndUpload/buildWithCompose.ts index d3a63054..4aff5894 100644 --- a/src/tasks/buildAndUpload/buildWithCompose.ts +++ b/src/tasks/buildAndUpload/buildWithCompose.ts @@ -1,3 +1,4 @@ +import { taskLog } from "../../utils/progress.js"; import { ListrTask } from "listr"; import { PackageImage } from "../../types.js"; import { shell } from "../../utils/shell.js"; @@ -5,6 +6,7 @@ import { saveAndCompressImagesCached } from "../saveAndCompressImages.js"; import { Compose, Manifest, defaultArch } from "@dappnode/types"; import { tmpComposeFileName } from "../../params.js"; import path from "path"; +import fs from "fs"; import { writeTmpCompose } from "./writeTmpCompose.js"; /** @@ -13,6 +15,7 @@ import { writeTmpCompose } from "./writeTmpCompose.js"; * A local cache file will prevent unnecessary compressions if the image hasn't changed */ export function buildWithCompose({ + architecture = defaultArch, images, compose, manifest, @@ -21,6 +24,7 @@ export function buildWithCompose({ skipSave, rootDir }: { + architecture?: import("@dappnode/types").Architecture; images: PackageImage[]; compose: Compose; manifest: Manifest; @@ -42,26 +46,38 @@ export function buildWithCompose({ return [ { title: "Build docker image", + enabled: () => images.some(image => image.type === "local"), task: async (_, task) => { // Prior to this task, the compose should had been updated with the proper tag - await shell(`docker compose --file ${tmpComposePath} build`, { - timeout: buildTimeout, - maxBuffer: 100 * 1e6, - onData: data => (task.output = data) - }); + await shell( + [ + "docker", + "compose", + "--progress", + "plain", + "--file", + tmpComposePath, + "build" + ], + { + timeout: buildTimeout, + maxBuffer: 100 * 1e6, + onData: taskLog(task) + } + ); } }, ...saveAndCompressImagesCached({ images, - architecture: defaultArch, + architecture, destPath, buildTimeout, skipSave }), { title: "Cleanup temporary files", - task: async () => shell(`rm ${tmpComposePath}`) + task: async () => fs.promises.rm(tmpComposePath, { force: true }) } ]; } diff --git a/src/tasks/buildAndUpload/generatePackagesProps.ts b/src/tasks/buildAndUpload/generatePackagesProps.ts index 8a44b115..9a1fbc8e 100644 --- a/src/tasks/buildAndUpload/generatePackagesProps.ts +++ b/src/tasks/buildAndUpload/generatePackagesProps.ts @@ -112,7 +112,7 @@ function getUpstreamVersion({ ); } -function getReleaseDirPath({ +export function getReleaseDirPath({ rootDir, dnpName, version diff --git a/src/tasks/buildAndUpload/getBuildTasks.ts b/src/tasks/buildAndUpload/getBuildTasks.ts index e0005e91..d1964d7a 100644 --- a/src/tasks/buildAndUpload/getBuildTasks.ts +++ b/src/tasks/buildAndUpload/getBuildTasks.ts @@ -25,19 +25,23 @@ export function getBuildTasks({ skipSave?: boolean; rootDir: string; }): ListrTask[] { - const buildTasks: ListrTask[] = packagesToBuildProps.flatMap((pkgProps) => { - return pkgProps.architectures.map(architecture => - createBuildTask({ - pkgProps, - architecture, - buildTimeout, - skipSave, - rootDir - }) - ); - }); + const buildTasks: ListrTask[] = + packagesToBuildProps.flatMap(pkgProps => { + return pkgProps.architectures.map(architecture => + createBuildTask({ + pkgProps, + architecture, + buildTimeout, + skipSave, + rootDir + }) + ); + }); - return buildTasks; + return buildTasks.map((task, index) => ({ + ...task, + title: `[${index + 1}/${buildTasks.length}] ${task.title}` + })); } function createBuildTask({ @@ -66,7 +70,7 @@ function createBuildTask({ }); return { - title: `Build ${name} (version ${version}) for arch ${architecture}`, + title: `Build ${pkgProps.variant || name.split(".")[0]} ${version} · ${architecture}`, task: () => new Listr( buildFn({ diff --git a/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts b/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts index 4d253cea..a59b4dda 100644 --- a/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts +++ b/src/tasks/buildAndUpload/getDeleteOldPinsTask.ts @@ -17,22 +17,34 @@ export function getDeleteOldPinsTask({ return { title: "Delete old pins", enabled: () => deleteOldPins, - task: async (_, task) => { - const gitHead = await getGitHead(); + skip: ctx => + !packagesToBuildProps.some( + pkg => ctx[pkg.manifest.name]?.releaseMultiHash + ), + task: async (ctx, task) => { if (releaseUploaderProvider.type !== "pinata") throw Error("Must use pinata for deleteOldPins"); // Unpin items on the same branch but previous (ancestor) commits const pinata = new PinataPinManager(releaseUploaderProvider); - for (const { manifest } of packagesToBuildProps) { + for (const { manifest, manifestPaths } of packagesToBuildProps) { + // Never remove the previous release until its replacement was uploaded. + if (!ctx[manifest.name]?.releaseMultiHash) continue; + const gitHead = await getGitHead(manifestPaths[0]?.dir); const pinsToDelete = await fetchPinsWithBranchToDelete( pinata, manifest, - gitHead + gitHead, + manifestPaths[0]?.dir ); for (const pin of pinsToDelete) { + if ( + pin.ipfsHash === + ctx[manifest.name].releaseMultiHash?.replace(/^\/ipfs\//, "") + ) + continue; task.output = `Unpinning previous commit ${pin.commit} ${pin.ipfsHash}`; await pinata.unpin(pin.ipfsHash).catch(e => { console.error(`Error deleting old pin ${pin.ipfsHash}`, e); diff --git a/src/tasks/buildAndUpload/getFileCopyTask.ts b/src/tasks/buildAndUpload/getFileCopyTask.ts index 485a065e..040bd5f9 100644 --- a/src/tasks/buildAndUpload/getFileCopyTask.ts +++ b/src/tasks/buildAndUpload/getFileCopyTask.ts @@ -1,4 +1,5 @@ import fs from "fs"; +import yaml from "js-yaml"; import path from "path"; import { ListrTask } from "listr/index.js"; import { verifyAvatar } from "../../utils/verifyAvatar.js"; @@ -56,8 +57,12 @@ async function copyFilesToReleaseDir({ requireGitData?: boolean; }): Promise { for (const variantProps of packagesToBuildProps) { - - await copyVariantFilesToReleaseDir({ variantProps, rootDir, variantsDirPath, composeFileName }); + await copyVariantFilesToReleaseDir({ + variantProps, + rootDir, + variantsDirPath, + composeFileName + }); // Verify avatar (throws) const avatarPath = path.join( @@ -67,7 +72,7 @@ async function copyFilesToReleaseDir({ verifyAvatar(avatarPath); // Make sure git data is available before doing a long build - await getGitHeadIfAvailable({ requireGitData }); + await getGitHeadIfAvailable({ requireGitData, dir: rootDir }); } } @@ -82,14 +87,26 @@ async function copyVariantFilesToReleaseDir({ variantsDirPath: string; composeFileName: string; }): Promise { - const { manifest, manifestFormat, releaseDir, compose, variant } = variantProps; + const { + manifest, + manifestFormat, + releaseDir, + compose, + variant, + notifications, + setupWizard + } = variantProps; // In case of single variant packages, the targets are in the root dir - const variantDirPath = variant ? path.join(variantsDirPath, variant) : rootDir; + const variantDirPath = variant + ? path.join(variantsDirPath, variant) + : rootDir; for (const [fileId, fileConfig] of Object.entries(releaseFiles)) { // For single variant packages, the targets are in the root dir - const dirsToCopy = fs.existsSync(variantDirPath) ? [rootDir, variantDirPath] : [rootDir]; + const dirsToCopy = fs.existsSync(variantDirPath) + ? [rootDir, variantDirPath] + : [rootDir]; switch (fileId as keyof typeof releaseFiles) { case "manifest": @@ -100,35 +117,66 @@ async function copyVariantFilesToReleaseDir({ writeReleaseCompose({ compose, composeFileName, manifest, releaseDir }); break; - case "prometheusTargets": - // Copy the targets in root and in the variant dir - for (const dir of dirsToCopy) { - copyReleaseFile({ - fileConfig: { ...fileConfig, id: fileId }, - fromDir: dir, - toDir: releaseDir - }); - } + case "notifications": + if (notifications) + fs.writeFileSync( + path.join(releaseDir, releaseFilesDefaultNames.notifications), + yaml.dump(notifications) + ); break; - case "notifications": - // Copy the notifications in root and in the variant dir - for (const dir of dirsToCopy) { + case "setupWizard": + if (setupWizard) + fs.writeFileSync( + path.join(releaseDir, releaseFilesDefaultNames.setupWizard), + JSON.stringify(setupWizard, null, 2) + "\n" + ); + break; + + case "prometheusTargets": { + // Only one targets file per release: the variant's replaces the root's, + // because scrape targets differ per variant (docs/dev/metrics.md). + const sourceDir = [...new Set(dirsToCopy)] + .filter(dir => + fs.readdirSync(dir).some(file => fileConfig.regex.test(file)) + ) + .pop(); + if (!sourceDir) break; + const files = fs + .readdirSync(sourceDir) + .filter(file => fileConfig.regex.test(file)); + if (files.length > 1) + throw new Error( + `More than one prometheusTargets file found in ${sourceDir}: ${files.join( + ", " + )}. Only one file can match ${fileConfig.regex}` + ); + // Normalise YAML sources so the released .json file is valid JSON. + const targets = yaml.load( + fs.readFileSync(path.join(sourceDir, files[0]), "utf8") + ); + fs.writeFileSync( + path.join(releaseDir, releaseFilesDefaultNames.prometheusTargets), + JSON.stringify(targets, null, 2) + "\n" + ); + break; + } + + default: { + const candidates = [...new Set(dirsToCopy)].filter(dir => + fs.readdirSync(dir).some(file => fileConfig.regex.test(file)) + ); + const sources = fileConfig.multiple + ? candidates + : [candidates.pop() || rootDir]; + for (const fromDir of sources) copyReleaseFile({ fileConfig: { ...fileConfig, id: fileId }, - fromDir: dir, + fromDir, toDir: releaseDir }); - } - break; - - default: - copyReleaseFile({ - fileConfig: { ...fileConfig, id: fileId }, - fromDir: rootDir, - toDir: releaseDir - }); break; + } } } } diff --git a/src/tasks/buildAndUpload/getFileValidationTask.ts b/src/tasks/buildAndUpload/getFileValidationTask.ts index e431c11b..7672e14f 100644 --- a/src/tasks/buildAndUpload/getFileValidationTask.ts +++ b/src/tasks/buildAndUpload/getFileValidationTask.ts @@ -1,7 +1,6 @@ import { ListrTask } from "listr/index.js"; import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { - validateComposeSchema, validateManifestSchema, validateSetupWizardSchema, validateDappnodeCompose, @@ -11,7 +10,9 @@ import { getComposePath, stripComposeVersion as removeComposeVersion } from "../../files/index.js"; +import { cloneDeep } from "lodash-es"; import { CliError } from "../../params.js"; +import { shell, ShellError } from "../../utils/shell.js"; export function getFileValidationTask({ packagesToBuildProps, @@ -24,73 +25,154 @@ export function getFileValidationTask({ }): ListrTask { return { title: `Validate files`, - task: async () => - await validatePackageFiles({ + task: async (ctx, task) => { + const coercions = await validatePackageFiles({ packagesToBuildProps, skipComposeValidation, - stripComposeVersion - }) + stripComposeVersion, + onStatus: message => { + task.output = message; + } + }); + // Release files are written from the validated objects, so coerced values are + // what ships. Keep the warning in the title so it stays visible after completion. + if (coercions.length > 0) + task.title = `Validate files (warning: schema validation changed ${ + coercions.length + } value(s), fix the source files: ${coercions.slice(0, 5).join("; ")}${ + coercions.length > 5 ? "; ..." : "" + })`; + } }; } async function validatePackageFiles({ packagesToBuildProps, skipComposeValidation, - stripComposeVersion + stripComposeVersion, + onStatus }: { packagesToBuildProps: PackageToBuildProps[]; skipComposeValidation?: boolean; stripComposeVersion?: boolean; -}): Promise { - for (const pkgProps of packagesToBuildProps) - await validateVariantFiles( - pkgProps, - skipComposeValidation, - stripComposeVersion + onStatus: (message: string) => void; +}): Promise { + const coercions: string[] = []; + for (const pkgProps of packagesToBuildProps) { + onStatus(`Validating ${pkgProps.manifest.name}`); + coercions.push( + ...(await validateVariantFiles( + pkgProps, + skipComposeValidation, + stripComposeVersion + )) ); + } + return coercions; } async function validateVariantFiles( pkgProps: PackageToBuildProps, skipComposeValidation?: boolean, stripComposeVersion?: boolean -): Promise { - const { - manifest, - compose, - composePaths, - notifications, - setupWizard - } = pkgProps; - - console.log( - `Validating files for ${manifest.name} (version ${manifest.version})` - ); +): Promise { + const { manifest, compose, composePaths, notifications, setupWizard } = + pkgProps; + const coercions: string[] = []; + const label = (file: string) => `${manifest.name} ${file}`; // Validate manifest schema - validateManifestSchema(manifest); + coercions.push( + ...validateReportingCoercions( + label("manifest"), + manifest, + validateManifestSchema + ) + ); validatePackageName(manifest.name); validatePackageVersion(manifest.version); // Validate compose file using docker compose - await validateComposeSchema( - composePaths.map(pathObj => getComposePath(pathObj)) - ); + try { + await shell([ + "docker", + "compose", + ...composePaths.flatMap(spec => ["-f", getComposePath(spec)]), + "config", + "--quiet" + ]); + } catch (e) { + if (!(e instanceof ShellError)) throw e; + throw new CliError(`Invalid compose:\n${e.stderr.trim() || e.message}`); + } // Validate compose file specifically for Dappnode requirements - if (skipComposeValidation) { - console.log(`Skipping Dappnode compose validation for ${manifest.name}`); - } else { + if (!skipComposeValidation) { validateDappnodeCompose(compose, manifest); } // Validate notifications schema - if (notifications) validateNotificationsSchema(notifications); + if (notifications) + coercions.push( + ...validateReportingCoercions( + label("notifications"), + notifications, + validateNotificationsSchema + ) + ); + if (setupWizard) + coercions.push( + ...validateReportingCoercions( + label("setup-wizard"), + setupWizard, + validateSetupWizardSchema + ) + ); // Keep version available for the Dappnode validation above. Stripping is // opt-in while support for versionless Compose files is being tested. if (stripComposeVersion) removeComposeVersion(compose); + return coercions; +} + +/** + * The schemas validate with type coercion, which mutates the object in place. + * Returns a description of every value the validator changed. + */ +export function validateReportingCoercions( + label: string, + value: T, + validate: (value: T) => unknown +): string[] { + const before = cloneDeep(value); + validate(value); + return changedPaths(before, value).map(change => `${label} ${change}`); +} + +function changedPaths(before: unknown, after: unknown, at = ""): string[] { + if ( + before !== null && + after !== null && + typeof before === "object" && + typeof after === "object" + ) { + const keys = new Set([...Object.keys(before), ...Object.keys(after)]); + return [...keys].flatMap(key => + changedPaths( + (before as Record)[key], + (after as Record)[key], + at ? `${at}.${key}` : key + ) + ); + } + return Object.is(before, after) + ? [] + : [ + `${at || "(root)"}: ${JSON.stringify(before)} -> ${JSON.stringify( + after + )}` + ]; } function validatePackageName(name: string): void { diff --git a/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts b/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts index af5b8f73..929c22dc 100644 --- a/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts +++ b/src/tasks/buildAndUpload/getReleaseDirCreationTask.ts @@ -1,7 +1,6 @@ import fs from "fs"; import path from "path"; import { ListrTask } from "listr/index.js"; -import rimraf from "rimraf"; import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getImageFileName } from "../../utils/getImageFileName.js"; @@ -29,14 +28,10 @@ function createReleaseDirs({ releaseDir, architectures } of packagesToBuildProps) { - console.log( - `Creating release directory for ${name} (version ${version}) at ${releaseDir}` - ); - fs.mkdirSync(releaseDir, { recursive: true }); // Ok on existing dir const releaseFiles = fs.readdirSync(releaseDir); - ctx[name] = { variant, releaseDir }; + ctx[name] = { ...ctx[name], variant, releaseDir }; const imagePaths = architectures.map(arch => getImageFileName(name, version, arch) @@ -45,6 +40,9 @@ function createReleaseDirs({ // Clean all files except the expected target images for (const filepath of releaseFiles) if (!imagePaths.includes(filepath)) - rimraf.sync(path.join(releaseDir, filepath)); + fs.rmSync(path.join(releaseDir, filepath), { + recursive: true, + force: true + }); } } diff --git a/src/tasks/buildAndUpload/getUploadTasks.ts b/src/tasks/buildAndUpload/getUploadTasks.ts index 0523d4bd..33bb0ce5 100644 --- a/src/tasks/buildAndUpload/getUploadTasks.ts +++ b/src/tasks/buildAndUpload/getUploadTasks.ts @@ -2,7 +2,6 @@ import { ListrTask } from "listr/index.js"; import { PackageToBuildProps, ListrContextBuild } from "../../types.js"; import { getGitHeadIfAvailable } from "../../utils/git.js"; import { getPinMetadata } from "../../pinStrategy/index.js"; -import { PinKeyvaluesDefault } from "../../releaseUploader/pinata/index.js"; import { IReleaseUploader } from "../../releaseUploader/index.js"; import { composeDeleteBuildProperties } from "../../files/index.js"; @@ -21,24 +20,43 @@ export function getUploadTasks({ }): ListrTask[] { const uploadTasks: ListrTask[] = []; - for (const { manifest, releaseDir } of packagesToBuildProps) { + for (const { manifest, releaseDir, manifestPaths } of packagesToBuildProps) { const { name: dnpName } = manifest; uploadTasks.push({ title: `Upload release for ${dnpName} to ${releaseUploader.networkName}`, skip: () => skipUpload, task: async (ctx, task) => { - const gitHead = await getGitHeadIfAvailable({ requireGitData }); + const gitHead = await getGitHeadIfAvailable({ + requireGitData, + dir: manifestPaths[0]?.dir + }); // Remove `build` property AFTER building. Otherwise it may break ISO installations // https://github.com/dappnode/DAppNode_Installer/issues/161 composeDeleteBuildProperties({ dir: releaseDir, composeFileName }); - ctx[dnpName].releaseMultiHash = await releaseUploader.addFromFs({ - dirPath: releaseDir, - metadata: getPinMetadata(manifest, gitHead) as PinKeyvaluesDefault, - onProgress: percent => (task.output = percentToMessage(percent)) - }); + let waiting: ReturnType | undefined; + try { + ctx[dnpName].releaseMultiHash = await releaseUploader.addFromFs({ + dirPath: releaseDir, + metadata: getPinMetadata(manifest, gitHead), + onProgress: percent => (task.output = percentToMessage(percent)), + onUploadComplete: () => { + const started = Date.now(); + task.output = "Upload sent · waiting for pinning confirmation..."; + if (waiting) clearInterval(waiting); + waiting = setInterval( + () => { + task.output = `Waiting for pinning confirmation · ${Math.floor((Date.now() - started) / 1000)}s`; + }, + process.stdout.isTTY ? 1000 : 15000 + ); + } + }); + } finally { + if (waiting) clearInterval(waiting); + } } }); } diff --git a/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts b/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts index 03b326e7..70597429 100644 --- a/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts +++ b/src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.ts @@ -1,3 +1,4 @@ +import { releaseFiles } from "@dappnode/types"; import path from "path"; import fs from "fs"; import { Github } from "../../../providers/github/Github.js"; @@ -11,7 +12,10 @@ import { getNextGitTag } from "../getNextGitTag.js"; import { contentHashFileName } from "../../../params.js"; import { ReleaseDetailsMap } from "../types.js"; import { buildReleaseDetailsMap } from "../buildReleaseDetailsMap.js"; -import { compactManifestIfCore, composeDeleteBuildProperties } from "../../../files/index.js"; +import { + compactManifestIfCore, + composeDeleteBuildProperties +} from "../../../files/index.js"; /** * Create release @@ -34,21 +38,25 @@ export function getCreateReleaseTask({ const tag = getNextGitTag(releaseDetailsMap, isMultiVariant); + task.output = "Preparing release files..."; + prepareGithubReleaseFiles({ releaseDetailsMap, composeFileName }); + task.output = "Deleting existing release..."; await github.deleteReleaseAndAssets(tag); task.output = `Creating release for tag ${tag}...`; const releaseId = await github.createRelease(tag, { body: await getReleaseBody({ releaseDetailsMap }), - prerelease: true, // Until it is actually published to mainnet + prerelease: true // Until it is actually published to mainnet }); - task.output = "Preparing release directories for Github release..."; - prepareGithubReleaseFiles({ releaseDetailsMap, composeFileName }); - task.output = "Uploading assets..."; - await uploadAssets({ releaseDetailsMap, github, releaseId, isMultiVariant }); - + await uploadAssets({ + releaseDetailsMap, + github, + releaseId, + isMultiVariant + }); } }; } @@ -60,26 +68,21 @@ function prepareGithubReleaseFiles({ releaseDetailsMap: ReleaseDetailsMap; composeFileName?: string; }) { - for (const [, { releaseMultiHash, releaseDir }] of Object.entries(releaseDetailsMap)) { - + for (const [, { releaseMultiHash, releaseDir }] of Object.entries( + releaseDetailsMap + )) { const contentHashPath = path.join(releaseDir, `${contentHashFileName}`); - try { - - /** - * Plain text file which should contain the IPFS hash of the release - * Necessary for the installer script to fetch the latest content hash - * of the eth clients. The resulting hashes are used by the DAPPMANAGER - * to install an eth client when the user does not want to use a remote node - */ - fs.writeFileSync(contentHashPath, releaseMultiHash); - - compactManifestIfCore(releaseDir); - composeDeleteBuildProperties({ dir: releaseDir, composeFileName }); + /** + * Plain text file which should contain the IPFS hash of the release + * Necessary for the installer script to fetch the latest content hash + * of the eth clients. The resulting hashes are used by the DAPPMANAGER + * to install an eth client when the user does not want to use a remote node + */ + fs.writeFileSync(contentHashPath, releaseMultiHash); - } catch (e) { - console.error(`Error found while preparing files in ${releaseDir} for Github release`, e); - } + compactManifestIfCore(releaseDir); + composeDeleteBuildProperties({ dir: releaseDir, composeFileName }); } } @@ -105,11 +108,17 @@ async function uploadAssets({ await github.uploadReleaseAssets({ releaseId, assetsDir: releaseDir, - // Only upload yml, txz and dappnode_package.json files - matchPattern: /(.*\.ya?ml$)|(.*\.txz$)|(dappnode_package\.json)|(content-hash)/, + // Use the shared release-file definitions so optional artifacts are retained. + matchPattern: new RegExp( + [ + "\\.txz$", + `^${contentHashFileName}$`, + ...Object.entries(releaseFiles) + .filter(([id]) => id !== "avatar") + .map(([, spec]) => spec.regex.source) + ].join("|") + ), fileNamePrefix: isMultiVariant ? `${shortDnpName}_` : "" - }).catch((e) => { - console.error(`Error uploading assets from ${releaseDir}`, e); }); } } @@ -126,19 +135,16 @@ async function uploadAvatar({ await github.uploadReleaseAssets({ releaseId, assetsDir: avatarDir, - matchPattern: /.*\.png/, - }).catch((e) => { - console.error(`Error uploading avatar from ${avatarDir}`, e); + matchPattern: /.*\.png/ }); } - /** * Write the release body * */ async function getReleaseBody({ - releaseDetailsMap, + releaseDetailsMap }: { releaseDetailsMap: ReleaseDetailsMap; }) { @@ -155,15 +161,15 @@ function getPackageVersionsTable(releaseDetailsMap: ReleaseDetailsMap) { Package | Version | Hash | Install | Publish --- | --- | --- | --- | --- ${Object.entries(releaseDetailsMap) - .map(([dnpName, { nextVersion, releaseMultiHash, txData }]) => - getPackageVersionsRow({ - dnpName, - nextVersion, - releaseMultiHash, - txData - }) - ) - .join("\n")} + .map(([dnpName, { nextVersion, releaseMultiHash, txData }]) => + getPackageVersionsRow({ + dnpName, + nextVersion, + releaseMultiHash, + txData + }) + ) + .join("\n")} `.trim(); } diff --git a/src/tasks/generatePublishTxs/index.ts b/src/tasks/generatePublishTxs/index.ts index 99cb31a8..41b049a9 100644 --- a/src/tasks/generatePublishTxs/index.ts +++ b/src/tasks/generatePublishTxs/index.ts @@ -4,8 +4,13 @@ import { getEthereumUrl } from "../../utils/getEthereumUrl.js"; import { getPublishTxLink } from "../../utils/getLinks.js"; import { addReleaseTx } from "../../utils/releaseRecord.js"; import { defaultDir, YargsError } from "../../params.js"; -import { PackageToBuildProps, CliGlobalOptions, ListrContextPublish, TxData } from "../../types.js"; -import { ApmRepository } from "@dappnode/toolkit"; +import { + PackageToBuildProps, + CliGlobalOptions, + ListrContextPublish, + TxData +} from "../../types.js"; +import { ApmRepository } from "../../providers/apm/ApmRepository.js"; import registryAbi from "../../contracts/ApmRegistryAbi.json" with { type: "json" }; import { semverToArray } from "../../utils/semverToArray.js"; import repoAbi from "../../contracts/RepoAbi.json" with { type: "json" }; @@ -32,7 +37,7 @@ export function generatePublishTxs({ developerAddress, ethProvider, verbosityOptions, - packagesToBuildProps, + packagesToBuildProps }: { developerAddress?: string; ethProvider: string; @@ -51,7 +56,6 @@ export function generatePublishTxs({ const contractAddress = "0x0000000000000000000000000000000000000000"; for (const { manifest } of packagesToBuildProps) { - const { name: dnpName, version } = manifest; const releaseMultiHash = ctx[dnpName]?.releaseMultiHash; @@ -118,22 +122,22 @@ export async function buildTxData({ return repository ? await getTxDataForExistingRepo({ - repository, - version, - contractAddress, - contentURI, - releaseMultiHash, - dnpName: dnpName - }) + repository, + version, + contractAddress, + contentURI, + releaseMultiHash, + dnpName: dnpName + }) : await getTxDataForNewRepo({ - dnpName: dnpName, - version, - contractAddress, - contentURI, - releaseMultiHash, - developerAddress, - ethereumUrl - }); + dnpName: dnpName, + version, + contractAddress, + contentURI, + releaseMultiHash, + developerAddress, + ethereumUrl + }); } async function getRepoContractIfExists({ diff --git a/src/tasks/generatePublishTxs/types.ts b/src/tasks/generatePublishTxs/types.ts index 7c7129fb..90697c52 100644 --- a/src/tasks/generatePublishTxs/types.ts +++ b/src/tasks/generatePublishTxs/types.ts @@ -1,3 +1,3 @@ -import { ApmRepository } from "@dappnode/toolkit"; +import { ApmRepository } from "../../providers/apm/ApmRepository.js"; export type Repo = Awaited>; diff --git a/src/tasks/publish/subtasks/getBuildAndUploadTask.ts b/src/tasks/publish/subtasks/getBuildAndUploadTask.ts index 070d09da..cd1d036e 100644 --- a/src/tasks/publish/subtasks/getBuildAndUploadTask.ts +++ b/src/tasks/publish/subtasks/getBuildAndUploadTask.ts @@ -3,7 +3,6 @@ import { BuildAndUploadOptions } from "../../buildAndUpload/types.js"; import { ListrContextPublish } from "../../../types.js"; import { buildAndUpload } from "../../buildAndUpload/index.js"; import { VerbosityOptions } from "../../../commands/build/types.js"; -import { merge } from "lodash-es"; export function getBuildAndUploadTask({ buildOptions, @@ -14,16 +13,6 @@ export function getBuildAndUploadTask({ }): ListrTask { return { title: "Building and uploading", - task: async ctx => { - const buildTasks = new Listr( - buildAndUpload(buildOptions), - verbosityOptions - ); - - const buildResults = await buildTasks.run(); - - // Add build results to publish context - ctx = merge(ctx, buildResults); - } + task: () => new Listr(buildAndUpload(buildOptions), verbosityOptions) }; } diff --git a/src/tasks/publish/subtasks/getUpdateFilesTask.ts b/src/tasks/publish/subtasks/getUpdateFilesTask.ts index 7b72d19e..220aa36f 100644 --- a/src/tasks/publish/subtasks/getUpdateFilesTask.ts +++ b/src/tasks/publish/subtasks/getUpdateFilesTask.ts @@ -1,4 +1,5 @@ import path from "path"; +import { getReleaseDirPath } from "../../buildAndUpload/generatePackagesProps.js"; import { ListrTask } from "listr"; import { PackageToBuildProps, ListrContextPublish } from "../../../types.js"; import { @@ -14,7 +15,7 @@ export function getUpdateFilesTask({ rootDir, variantsDirPath, composeFileName, - packagesToBuildProps, + packagesToBuildProps }: { rootDir: string; variantsDirPath: string; @@ -25,7 +26,12 @@ export function getUpdateFilesTask({ title: "Update compose and manifest files", task: async ctx => { for (const pkgProps of packagesToBuildProps) { - const { variant, manifest: { name }, composePaths, manifestPaths } = pkgProps; + const { + variant, + manifest: { name }, + composePaths, + manifestPaths + } = pkgProps; const nextVersion = ctx[name].nextVersion; if (!nextVersion) { @@ -40,7 +46,7 @@ export function getUpdateFilesTask({ variant, variantsDirPath, dnpName: name, - nextVersion, + nextVersion }); const newCompose = readCompose(composePaths); @@ -49,6 +55,12 @@ export function getUpdateFilesTask({ // Update variantsMap entry pkgProps.compose = newCompose; pkgProps.manifest = newManifest; + pkgProps.releaseDir = getReleaseDirPath({ + rootDir, + dnpName: name, + version: nextVersion + }); + ctx[name].releaseDir = pkgProps.releaseDir; pkgProps.images = getComposePackageImages(newCompose, newManifest); } } @@ -62,7 +74,7 @@ export function updateVariantFiles({ variant, variantsDirPath, dnpName, - nextVersion, + nextVersion }: { rootDir: string; composeFileName: string; @@ -120,10 +132,10 @@ function updateComposeFileImages({ const newCompose = updateComposeImageTags(compose, { name: dnpName, version: nextVersion - }, { editExternalImages: true }); + }); writeCompose(newCompose, { dir: composeDir, composeFileName }); -} \ No newline at end of file +} diff --git a/src/tasks/saveAndCompressImages.ts b/src/tasks/saveAndCompressImages.ts index 79cdb5ae..b56cf64a 100644 --- a/src/tasks/saveAndCompressImages.ts +++ b/src/tasks/saveAndCompressImages.ts @@ -1,6 +1,7 @@ import fs from "fs"; import path from "path"; -import { spawn } from "child_process"; +import { spawn, ChildProcess } from "child_process"; +import { pipeline } from "stream/promises"; import { ListrTask } from "listr"; import { getFileHash } from "../utils/getFileHash.js"; import { loadCache, writeToCache, getCacheKey } from "../utils/cache.js"; @@ -42,14 +43,17 @@ export function saveAndCompressImagesCached({ task: async (_, task) => { for (const { imageTag, originalImageTag } of externalImages) { await shell( - `docker pull ${originalImageTag} --platform=${architecture}`, + ["docker", "pull", `--platform=${architecture}`, originalImageTag], { onData: data => (task.output = data) } ); task.output = `Tagging ${originalImageTag} > ${imageTag}`; - await shell(`docker tag ${originalImageTag} ${imageTag}`); + await shell(["docker", "tag", originalImageTag, imageTag]); // Validate the resulting image architecture - const imageDataRaw = await shell(`docker image inspect --platform=${architecture} ${imageTag}`); + const imageDataRaw = await inspectImageForPlatform( + imageTag, + architecture + ); const imageData = JSON.parse(imageDataRaw); const imageArch = `${imageData[0]["Os"]}/${imageData[0]["Architecture"]}`; if (imageArch !== architecture) @@ -91,7 +95,32 @@ export function saveAndCompressImagesCached({ ]; } -async function saveAndCompressImages({ +/** + * With the containerd image store a tag can hold several platforms, and a plain + * inspect reports the host platform (or none). `--platform` selects the pulled one. + * Docker CLI < 28.1 lacks the flag; there a tag holds one platform, so a plain inspect is exact. + */ +export async function inspectImageForPlatform( + imageTag: string, + architecture: Architecture +): Promise { + try { + return await shell([ + "docker", + "image", + "inspect", + `--platform=${architecture}`, + imageTag + ]); + } catch (e) { + const output = `${e.message || ""}\n${e.stderr || ""}`; + if (!/unknown flag: --platform/i.test(output)) throw e; + return await shell(["docker", "image", "inspect", imageTag]); + } +} + +/** Export atomically only after both processes and both pipes have succeeded. */ +export async function saveAndCompressImages({ imageTags, destPath, onData, @@ -102,50 +131,70 @@ async function saveAndCompressImages({ onData?: (data: string) => void; timeout?: number; }): Promise { - return new Promise((resolve, reject) => { - const dockerSave = spawn("docker", ["save", ...imageTags]); - - // -e9T0: Compression settings (extreme and paralelized) - // -vv: Very verbose log to provide progress - // -c: Outputs the compressed result to stdout - // -f: Overwrite the destination path if necessary - const xz = spawn("xz", ["-e9T0", "-vv", "-c", "-f"], { timeout }); - - dockerSave.stdout.pipe(xz.stdin); - - let lastStderr = ""; - xz.stderr.on("data", chunk => { - const data = chunk.toString().trim(); - lastStderr = data; - if (onData) onData(data); - }); - - xz.stdout.pipe(fs.createWriteStream(destPath)); - - // In order for xz to output update logs to stderr, - // a SIGALRM must be sent to the xz process every interval - // https://stackoverflow.com/questions/48452726/how-to-redirect-xzs-normal-stdout-when-do-tar-xz - const interval = setInterval(() => xz.kill("SIGALRM"), 1000); - - xz.on("error", err => { - clearInterval(interval); - reject(Error(`Error compressing image: ${err.message} \n${lastStderr}`)); - }); + await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); + const temporaryDir = await fs.promises.mkdtemp( + path.join(path.dirname(destPath), ".dappnodesdk-") + ); + const temporaryPath = path.join(temporaryDir, "image.txz"); + const dockerSave = spawn("docker", ["save", ...imageTags]); + const xz = spawn("xz", ["-e9T0", "-vv", "-c"]); + let dockerStderr = ""; + let compressionStderr = ""; + dockerSave.stderr.on("data", (chunk: Buffer) => { + dockerStderr = (dockerStderr + chunk.toString()).slice(-65536); + }); + xz.stderr.on("data", (chunk: Buffer) => { + const message = chunk.toString().trim(); + compressionStderr = (compressionStderr + message).slice(-65536); + if (message && onData) onData(message); + }); - xz.on("exit", code => { - clearInterval(interval); - if (code) { - reject( - Error(`Error compressing image: xz exit ${code} \n${lastStderr}`) - ); - } else { - resolve(`Compressed image saved to ${destPath}`); - } + const completed = ( + child: ChildProcess, + label: string, + stderr: () => string + ): Promise => + new Promise((resolve, reject) => { + child.once("error", reject); + child.once("close", (code, signal) => { + if (code === 0 && !signal) resolve(); + else + reject( + new Error( + `${label} failed (${signal || `exit ${code}`}): ${stderr()}` + ) + ); + }); }); - dockerSave.on("error", err => { - clearInterval(interval); - reject(Error(`Error saving image: ${err.message}`)); - }); + let timer: ReturnType | undefined; + const timeoutPromise = new Promise((resolve, reject) => { + if (timeout && timeout > 0) + timer = setTimeout( + () => reject(new Error(`Image export timed out after ${timeout} ms`)), + timeout + ); }); + const interval = setInterval(() => xz.kill("SIGALRM"), 1000); + try { + await Promise.race([ + Promise.all([ + completed(dockerSave, "docker save", () => dockerStderr), + completed(xz, "xz", () => compressionStderr), + pipeline(dockerSave.stdout, xz.stdin), + pipeline(xz.stdout, fs.createWriteStream(temporaryPath)) + ]), + timeoutPromise + ]); + await fs.promises.rename(temporaryPath, destPath); + return `Compressed image saved to ${destPath}`; + } catch (error) { + dockerSave.kill("SIGKILL"); + xz.kill("SIGKILL"); + throw error; + } finally { + clearInterval(interval); + if (timer) clearTimeout(timer); + await fs.promises.rm(temporaryDir, { recursive: true, force: true }); + } } diff --git a/src/timestring.d.ts b/src/timestring.d.ts new file mode 100644 index 00000000..aa8d59e8 --- /dev/null +++ b/src/timestring.d.ts @@ -0,0 +1,3 @@ +declare module "timestring/index.js" { + export default function timestring(value: string): number; +} diff --git a/src/utils/copyReleaseFile.ts b/src/utils/copyReleaseFile.ts index 42f83eee..2c2c55a2 100644 --- a/src/utils/copyReleaseFile.ts +++ b/src/utils/copyReleaseFile.ts @@ -37,7 +37,12 @@ export function copyReleaseFile({ } else if (matchingFiles.length === 1) { fs.copyFileSync( path.join(fromDir, matchingFiles[0]), - path.join(toDir, getDefaultName(fileConfig.id) || matchingFiles[0]) + path.join( + toDir, + (fileConfig.multiple + ? matchingFiles[0] + : getDefaultName(fileConfig.id)) || matchingFiles[0] + ) ); } else { if (fileConfig.multiple) { diff --git a/src/utils/file.ts b/src/utils/file.ts index 8dba6094..423c1d2b 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -10,7 +10,8 @@ export function readFile(filepath: string): string { } catch (e) { if (e.code === "ENOENT") { throw Error( - `${filepath} not found. Make sure you are in a directory with an initialized DNP.` + `${filepath} not found. Make sure you are in a directory with an initialized DNP.`, + { cause: e } ); } else { throw e; diff --git a/src/utils/formatCliError.ts b/src/utils/formatCliError.ts new file mode 100644 index 00000000..c711690d --- /dev/null +++ b/src/utils/formatCliError.ts @@ -0,0 +1,34 @@ +import chalk from "chalk"; +import { ShellError } from "./shell.js"; +import { wasTaskOutputStreamed } from "./progress.js"; + +/** + * Formats an error for the terminal, once. + * A failed command whose log was already streamed (verbose/CI) is reported by its summary line only; + * otherwise the message includes the last lines of its output. Stack frames are shown only with --debug/--verbose. + */ +export function formatCliError( + error: unknown, + { + debug = false, + outputStreamed = wasTaskOutputStreamed() + }: { debug?: boolean; outputStreamed?: boolean } = {} +): string { + const err = error instanceof Error ? error : new Error(String(error)); + const body = + err instanceof ShellError && err.streamed && outputStreamed + ? err.summary + : err.message; + const [first, ...rest] = body.trimEnd().split("\n"); + const lines = [ + `${chalk.red("✖")} ${first}`, + ...rest.map(line => ` ${line}`) + ]; + // `--verbose` is also `--debug`. The stack starts with the message, which is already + // printed above, so only the frames are added. + const frames = (err.stack || "") + .split("\n") + .filter(line => /^\s+at /.test(line)); + if (debug && frames.length > 0) lines.push(chalk.dim(frames.join("\n"))); + return lines.join("\n"); +} diff --git a/src/utils/getFileHash.ts b/src/utils/getFileHash.ts index 40ce2288..3d46c28e 100644 --- a/src/utils/getFileHash.ts +++ b/src/utils/getFileHash.ts @@ -12,7 +12,7 @@ export function getFileHash(path: string): Promise { const hash = crypto.createHash("sha256"); const stream = fs.createReadStream(path); - stream.on("data", (chunk: Buffer) => { + stream.on("data", (chunk: string | Buffer) => { hash.update(chunk); // Should now recognize Buffer correctly }); diff --git a/src/utils/getImageId.ts b/src/utils/getImageId.ts index 113f435b..670d8e5c 100644 --- a/src/utils/getImageId.ts +++ b/src/utils/getImageId.ts @@ -8,7 +8,12 @@ import { shell } from "./shell.js"; * @return formated ID: sha256:0d31e5521ef6e92a0efb6110024da8a3517daac4b1e4bbbccaf063ce96641b1b */ export async function getImageId(imageTag: string): Promise { - const id = await shell(`docker inspect --format='{{json .Id}}' ${imageTag}`); + const id = await shell([ + "docker", + "inspect", + "--format={{json .Id}}", + imageTag + ]); return id.replace(/['"]+/g, ""); } @@ -23,6 +28,6 @@ export async function getImageId(imageTag: string): Promise { * ] */ export async function getImageIds(): Promise { - const res = await shell(`docker images -q`); + const res = await shell(["docker", "images", "-q"]); return res.trim().split(/\r?\n/); } diff --git a/src/utils/git.ts b/src/utils/git.ts index 4449b34c..ac1bf6da 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -20,9 +20,15 @@ export interface GitHead { * branch: "dapplion/prepare-build-action" * ``` */ -export async function getGitHead(): Promise { - const commit = await shell("git rev-parse --verify HEAD"); - const branch = await shell("git rev-parse --abbrev-ref HEAD"); +export async function getGitHead(dir?: string): Promise { + const commit = await shell(["git", "rev-parse", "--verify", "HEAD"], { + cwd: dir + }); + let branch = await shell(["git", "rev-parse", "--abbrev-ref", "HEAD"], { + cwd: dir + }); + if (branch === "HEAD" && process.env.GITHUB_REF?.startsWith("refs/heads/")) + branch = process.env.GITHUB_REF.slice("refs/heads/".length); return { commit, branch }; } @@ -32,9 +38,10 @@ export async function getGitHead(): Promise { */ export async function getGitHeadIfAvailable(options?: { requireGitData?: boolean; + dir?: string; }): Promise { try { - return await getGitHead(); + return await getGitHead(options?.dir); } catch (e) { if (options?.requireGitData) { e.message = `Error on getGitHead: ${e.message}`; @@ -48,10 +55,14 @@ export async function getGitHeadIfAvailable(options?: { /** * @param branch dappnodebot/bump-upstream/go-ipfs@v0.7.0 */ -export async function getLocalBranchExists(branch: string): Promise { +export async function getLocalBranchExists( + branch: string, + dir?: string +): Promise { try { const branchSha = await shell( - `git show-ref --verify -s refs/heads/${branch}` + ["git", "show-ref", "--verify", "-s", `refs/heads/${branch}`], + { cwd: dir } ); return Boolean(branchSha); } catch (e) { diff --git a/src/utils/merge.ts b/src/utils/merge.ts new file mode 100644 index 00000000..fbcfe573 --- /dev/null +++ b/src/utils/merge.ts @@ -0,0 +1,12 @@ +import { cloneDeep, mergeWith } from "lodash-es"; + +/** + * Deep merge where an array from a later source replaces the earlier array. + * lodash `merge` combines arrays by index, so root `enum: [a, b, c]` plus a + * variant `enum: [mainnet]` would become `[mainnet, b, c]`, which neither file declares. + */ +export function mergeReplacingArrays(...sources: unknown[]): T { + return mergeWith({}, ...sources, (_base: unknown, override: unknown) => + Array.isArray(override) ? cloneDeep(override) : undefined + ); +} diff --git a/src/utils/progress.ts b/src/utils/progress.ts new file mode 100644 index 00000000..3fa45077 --- /dev/null +++ b/src/utils/progress.ts @@ -0,0 +1,206 @@ +import { createLogUpdate } from "log-update"; +import wrapAnsi from "wrap-ansi"; +import chalk from "chalk"; +import { stripVTControlCharacters } from "util"; +import type Listr from "listr"; + +const previewLines = 4; + +export interface ProgressTask { + title: string; + output?: string; + state?: string; + subtasks: readonly ProgressTask[]; + isEnabled(): boolean; + isPending(): boolean; + isCompleted(): boolean; + isSkipped(): boolean; + hasFailed(): boolean; +} + +interface ListrEvent { + type: string; + data?: string; +} + +interface ObservableTask extends ProgressTask { + subtasks: readonly ObservableTask[]; + subscribe(next: (event: ListrEvent) => void, error?: () => void): unknown; +} + +/** + * Report each complete log line once as the task output. + * Verbose renderers log every line exactly once; the terminal renderer keeps its own short history. + */ +export function taskLog(task: { output?: string }): (line: string) => void { + return line => { + task.output = stripVTControlCharacters(line); + }; +} + +/** Whether a renderer has streamed task output to the console, so a failed command's log was already shown. */ +let outputStreamed = false; +export function wasTaskOutputStreamed(): boolean { + return outputStreamed; +} + +/** + * Renders the task tree. A pending task shows its last few output lines. + * A failed task shows only its title, because listr sets the failed task's output to the error message + * and the CLI reports that error once, after rendering ends. + */ +export function renderProgress( + tasks: readonly ProgressTask[], + frame = "⠋", + depth = 0, + history?: WeakMap +): string[] { + const lines: string[] = []; + for (const task of tasks) { + if (!task.isEnabled()) continue; + const failed = task.hasFailed(); + const pending = task.isPending(); + if (!pending && !failed && !task.isCompleted() && !task.isSkipped()) + continue; + const symbol = failed + ? "✖" + : pending + ? frame + : task.isSkipped() + ? "↓" + : "✔"; + const indent = " ".repeat(depth); + lines.push(`${indent}${symbol} ${stripVTControlCharacters(task.title)}`); + if (pending) { + const recent = history + ? history.get(task) || [] + : stripVTControlCharacters(task.output || "").split(/\r?\n/); + for (const line of recent.slice(-previewLines)) + if (line.trim()) lines.push(`${indent} │ ${line}`); + } + if (pending || failed) + lines.push(...renderProgress(task.subtasks, frame, depth + 1, history)); + } + return lines; +} + +/** Calls `onEvent` for every event of every task, including subtasks created later. */ +function watchTasks( + tasks: readonly ObservableTask[], + onEvent: (task: ObservableTask, event: ListrEvent) => void +): void { + for (const task of tasks) + task.subscribe( + event => { + if (event.type === "SUBTASKS") watchTasks(task.subtasks, onEvent); + else onEvent(task, event); + }, + // Errors are reported once by the CLI, not by the renderer. + () => {} + ); +} + +/** One renderer owns the terminal; nested task lists share its bounded preview. */ +export class ProgressRenderer { + static nonTTY = false; + private readonly update = createLogUpdate(process.stdout); + private readonly history = new WeakMap(); + private interval?: ReturnType; + private frame = 0; + constructor( + private readonly tasks: ReadonlyArray> + ) {} + + private draw(): void { + const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + const lines = renderProgress( + this.tasks as unknown as readonly ProgressTask[], + frames[this.frame++ % frames.length], + 0, + this.history + ); + const rows = lines.flatMap(line => + wrapAnsi(line, Math.max(10, process.stdout.columns || 80), { + hard: true, + trim: false, + wordWrap: false + }).split("\n") + ); + this.update( + rows.slice(-Math.max(1, (process.stdout.rows || 24) - 2)).join("\n") + ); + } + + render(): void { + watchTasks( + this.tasks as unknown as readonly ObservableTask[], + (task, event) => { + if (event.type !== "DATA" || task.hasFailed() || !event.data) return; + const lines = this.history.get(task) || []; + lines.push(...stripVTControlCharacters(event.data).split(/\r?\n/)); + this.history.set(task, lines.slice(-previewLines)); + } + ); + this.draw(); + this.interval = setInterval(() => this.draw(), 100); + } + + end(): void { + if (this.interval) clearInterval(this.interval); + this.draw(); + this.update.done(); + } +} + +/** Line-by-line log for CI and --verbose: every output line once, without repeating the error. */ +export class VerboseRenderer { + static nonTTY = true; + constructor( + private readonly tasks: ReadonlyArray> + ) {} + + private log(message: string): void { + const time = new Date().toTimeString().slice(0, 8); + console.log(`${chalk.dim(`[${time}]`)} ${message}`); + } + + render(): void { + outputStreamed = true; + watchTasks( + this.tasks as unknown as readonly ObservableTask[], + (task, event) => { + if (event.type === "STATE") { + this.log( + `${task.title} [${task.isPending() ? "started" : task.state}]` + ); + if (task.isSkipped() && task.output) this.log(`→ ${task.output}`); + } else if (event.type === "DATA") { + // On failure listr sets the output to the error message; the CLI prints it once. + if (!task.hasFailed() && event.data) this.log(`→ ${event.data}`); + } else if (event.type === "TITLE") { + this.log(`${task.title} [title changed]`); + } + } + ); + } + + end(): void {} +} + +export function getRendererOptions({ + verbose, + silent +}: { + verbose?: boolean; + silent?: boolean; +}): { + renderer: "silent" | typeof ProgressRenderer | typeof VerboseRenderer; + nonTTYRenderer: "silent" | typeof VerboseRenderer; +} { + if (silent && !verbose) + return { renderer: "silent", nonTTYRenderer: "silent" }; + return { + renderer: verbose ? VerboseRenderer : ProgressRenderer, + nonTTYRenderer: VerboseRenderer + }; +} diff --git a/src/utils/shell.ts b/src/utils/shell.ts index 9772fb5f..045a9310 100644 --- a/src/utils/shell.ts +++ b/src/utils/shell.ts @@ -1,4 +1,11 @@ -import { exec, ExecException } from "child_process"; +import { + exec, + execFile, + ExecException, + ExecFileException +} from "child_process"; +import { StringDecoder } from "string_decoder"; +import { stripVTControlCharacters } from "util"; /** * If timeout is greater than 0, the parent will send the signal @@ -10,13 +17,8 @@ const defaultTimeout = 3 * 60 * 1000; // ms const defaultMaxBuffer = 1e7; // bytes /** - * Run arbitrary commands in a shell - * If the child process exits with code > 0, rejects - * Note: using exec instead of spawn since it's not as safe to run - * complex arbirary commands. For example: - * - The executable docker-compose may not be detected, causing ENOENT - * - Doing cmd > cmd2 may fail - * - Flags may not be passed properly + * Execute an argument array directly, or an intentional shell script as a string. + * Stream complete output lines while retaining stdout/stderr for failure diagnostics. */ export async function shell( cmd: string | string[], @@ -25,34 +27,73 @@ export async function shell( maxBuffer?: number; pipeToMain?: boolean; onData?: (data: string) => void; + cwd?: string; } ): Promise { const { timeout = defaultTimeout, maxBuffer = defaultMaxBuffer, pipeToMain = false, - onData + onData, + cwd } = options || {}; return new Promise((resolve, reject): void => { const cmdStr = Array.isArray(cmd) ? cmd.join(" ") : cmd; - const proc = exec(cmdStr, { timeout, maxBuffer }, (err, stdout, stderr) => { + const callback = ( + err: ExecException | ExecFileException | null, + stdout: string, + stderr: string + ): void => { if (err) { // Rethrow a typed error, and ignore the internal NodeJS stack trace - reject(new ShellError(err, { stdout, stderr, cmd: cmdStr })); + reject( + new ShellError(err, { + stdout, + stderr, + cmd: cmdStr, + streamed: Boolean(onData) + }) + ); } else { resolve(stdout.trim() || stderr); } - }); + }; + // Arrays are arguments, never shell source. Use strings only for intentional scripts. + const proc = Array.isArray(cmd) + ? execFile( + cmd[0], + cmd.slice(1), + { timeout, maxBuffer, cwd, encoding: "utf8" }, + callback + ) + : exec(cmd, { timeout, maxBuffer, cwd, encoding: "utf8" }, callback); if (pipeToMain) { if (proc.stdout) proc.stdout.pipe(process.stdout); if (proc.stderr) proc.stderr.pipe(process.stderr); } if (onData) { - const onChunkData = (chunk: Buffer): void => - onData(chunk.toString().trim()); - if (proc.stdout) proc.stdout.on("data", onChunkData); - if (proc.stderr) proc.stderr.on("data", onChunkData); + for (const stream of [proc.stdout, proc.stderr]) { + if (!stream) continue; + const decoder = new StringDecoder("utf8"); + let pending = ""; + const flush = (text: string): void => { + pending += text; + const lines = pending.split(/\r\n|[\r\n]/); + pending = lines.pop() || ""; + for (const line of lines) if (line.trim()) onData(line); + // Keep malformed/no-newline process output bounded as well. + if (pending.length > 65536) { + onData(pending.slice(0, 65536)); + pending = pending.slice(65536); + } + }; + stream.on("data", (chunk: Buffer) => flush(decoder.write(chunk))); + stream.on("end", () => { + flush(decoder.end()); + if (pending.trim()) onData(pending); + }); + } } }); } @@ -61,23 +102,39 @@ export async function shell( * Typed error implementing the native node child exception error * Can be rethrow to ignore the internal NodeJS stack trace */ +/** Lines of command output kept in the error message; the full streams stay on `stdout`/`stderr`. */ +const errorOutputLines = 20; + export class ShellError extends Error { cmd?: string; killed?: boolean; - code?: number; + code?: string | number | null; signal?: NodeJS.Signals; stdout: string; stderr: string; + /** One line describing what failed, e.g. "Command failed (exit 1): docker compose build". */ + summary: string; + /** True when the output was streamed to the task log while the command ran. */ + streamed: boolean; constructor( - e: ExecException, - { cmd, stdout, stderr }: { cmd: string; stdout: string; stderr: string } + e: ExecException | ExecFileException, + { + cmd, + stdout, + stderr, + streamed = false + }: { cmd: string; stdout: string; stderr: string; streamed?: boolean } ) { - const msg = [ - e.signal === "SIGTERM" ? `TIMEOUT: ${e.message}` : e.message, - `stdout: ${stdout}`, - `stderr: ${stderr}` - ].join("\n"); - super(msg); + const summary = + e.signal === "SIGTERM" + ? `TIMEOUT: command killed by SIGTERM: ${cmd}` + : e.signal + ? `Command killed by ${e.signal}: ${cmd}` + : typeof e.code === "number" + ? `Command failed (exit ${e.code}): ${cmd}` + : `Command failed (${e.code || e.message}): ${cmd}`; + const tail = outputTail(stderr.trim() ? stderr : stdout); + super(tail ? `${summary}\n${tail}` : summary); this.cmd = cmd; this.killed = e.killed; @@ -85,5 +142,19 @@ export class ShellError extends Error { this.signal = e.signal; this.stdout = stdout; this.stderr = stderr; + this.summary = summary; + this.streamed = streamed; } } + +/** Last lines of output without terminal control sequences or blank lines. */ +function outputTail(output: string): string { + const lines = stripVTControlCharacters(output) + .split(/\r?\n|\r/) + .filter(line => line.trim()); + const omitted = lines.length - errorOutputLines; + return [ + ...(omitted > 0 ? [`... (${omitted} earlier lines omitted)`] : []), + ...lines.slice(-errorOutputLines) + ].join("\n"); +} diff --git a/src/utils/timeout.ts b/src/utils/timeout.ts index a7ee0345..13734fb0 100644 --- a/src/utils/timeout.ts +++ b/src/utils/timeout.ts @@ -1,28 +1,24 @@ -// timestring does not have a @types package -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore import timestring from "timestring/index.js"; -// Define build timeout (60 min) const defaultBuildTimeout = 60 * 60 * 1000; /** - * Parses a timeout string and returns a number in miliseconds - * @param timeout "20min", "5000", undefined + * Parses a timeout and returns milliseconds. + * - Strings are human-readable durations ("20min", "1h"); a bare integer string ("5000") is seconds. + * - Numbers are already milliseconds; 0 disables the timeout, as before. */ -export function parseTimeout(timeout: string | undefined): number { - switch (typeof timeout) { - case "number": { - return timeout; - } - case "string": { - if (!timeout) defaultBuildTimeout; - // Timestring returns in seconds - const parsedString = timestring(timeout) || parseInt(timeout); - if (!parsedString) throw Error(`Error parsing timeout: ${timeout}`); - return parsedString * 1000; - } - default: - return defaultBuildTimeout; +export function parseTimeout(timeout: string | number | undefined): number { + if (timeout === undefined || timeout === "") return defaultBuildTimeout; + if (typeof timeout === "number") { + if (!Number.isFinite(timeout) || timeout < 0) + throw new Error(`Invalid timeout: ${timeout}`); + return timeout; } + const trimmed = timeout.trim(); + const parsed = /^\d+$/.test(trimmed) + ? Number(trimmed) * 1000 + : timestring(trimmed) * 1000; + if (!Number.isFinite(parsed) || parsed <= 0) + throw new Error(`Invalid timeout: ${timeout}`); + return parsed; } diff --git a/src/utils/verifyAvatar.ts b/src/utils/verifyAvatar.ts index 62c41e05..2fbd97c3 100644 --- a/src/utils/verifyAvatar.ts +++ b/src/utils/verifyAvatar.ts @@ -1,13 +1,12 @@ -import sizeOf from "image-size"; +import { imageSize } from "image-size"; +import fs from "fs"; import { CliError } from "../params.js"; const maxSize = 300; const minSize = 200; export function verifyAvatar(avatarPath: string): void { - // image-size has conflicting types to its documentation - // @ts-ignore - const { width, height } = sizeOf(avatarPath); + const { width, height } = imageSize(fs.readFileSync(avatarPath)); if (width !== height) throw new CliError(`Wrong avatar aspect ratio diff --git a/src/utils/versions/getNextVersionFromApm.ts b/src/utils/versions/getNextVersionFromApm.ts index 111c80d6..f97ee08d 100644 --- a/src/utils/versions/getNextVersionFromApm.ts +++ b/src/utils/versions/getNextVersionFromApm.ts @@ -2,7 +2,7 @@ import semver from "semver"; import { getEthereumUrl } from "../getEthereumUrl.js"; import { checkSemverType } from "../checkSemverType.js"; import { ReleaseType } from "../../types.js"; -import { ApmRepository } from "@dappnode/toolkit"; +import { ApmRepository } from "../../providers/apm/ApmRepository.js"; export async function getNextVersionFromApm({ type, diff --git a/test/commands/build.test.ts b/test/commands/build.test.ts index 3508b48c..2701bd5b 100644 --- a/test/commands/build.test.ts +++ b/test/commands/build.test.ts @@ -76,7 +76,7 @@ describe("Init and build simple package", function () { strip_compose_version: true }); - expect(readCompose([{ dir: releaseDir }]).version).to.be.undefined; + expect(readCompose([{ dir: releaseDir }]).version).to.equal(undefined); }); }); diff --git a/test/commands/buildProgress.test.ts b/test/commands/buildProgress.test.ts new file mode 100644 index 00000000..7c04ce20 --- /dev/null +++ b/test/commands/buildProgress.test.ts @@ -0,0 +1,135 @@ +import fs from "fs"; +import os from "os"; +import path from "path"; +import { execFile } from "child_process"; +import { promisify } from "util"; +import { expect } from "chai"; +import Listr from "listr"; +import { initHandler } from "../../src/commands/init/handler.js"; +import { buildWithCompose } from "../../src/tasks/buildAndUpload/buildWithCompose.js"; +import { + temporaryDirectory, + executable, + useExecutables +} from "../helpers/fixtures.js"; + +const execute = promisify(execFile); +describe("build commands and native architecture", function () { + this.timeout(15000); + let dir: string; + let bin: string; + let restorePath: () => void; + beforeEach(async () => { + dir = temporaryDirectory(); + bin = path.join(dir, "bin"); + await initHandler({ dir, yes: true, force: true }); + const manifestPath = path.join(dir, "dappnode_package.json"); + const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); + manifest.architectures = ["linux/amd64", "linux/arm64"]; + fs.writeFileSync(manifestPath, JSON.stringify(manifest)); + executable( + bin, + "docker", + ` + const fs = require('fs'); + const args = process.argv.slice(2); + if (args[0] === 'pull') fs.appendFileSync(${JSON.stringify(path.join(dir, "pulls.jsonl"))}, JSON.stringify(args)+'\\n'); + if (args[0] === 'image') console.log(JSON.stringify([{Os:'linux',Architecture:'arm64'}])); + if (args[0] === 'compose' && args.includes('build')) {process.stdout.write('building'); setTimeout(() => process.stdout.write(' layer\\n'), 15);} + ` + ); + restorePath = useExecutables(bin); + }); + afterEach(() => { + restorePath(); + fs.rmSync(dir, { recursive: true, force: true }); + }); + + it("reports a successful build when --skip-save implicitly skips uploading", async () => { + const arch = os.arch() === "arm64" ? "arm64" : "amd64"; + const { stdout } = await execute(process.execPath, [ + "--import=tsx", + "src/dappnodesdk.ts", + "build", + "--dir", + dir, + "--arch", + arch, + "--skip-save" + ]); + expect(stdout).to.include("DNP (DAppNode Package) built"); + expect(stdout).not.to.include("Error building"); + expect(stdout).to.include("building layer"); + }); + + it("shows resolved variant names and builds each selected template", async () => { + await initHandler({ dir, yes: true, force: true, use_variants: true }); + const manifestPath = path.join(dir, "dappnode_package.json"); + const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")); + manifest.architectures = ["linux/amd64", "linux/arm64"]; + fs.writeFileSync(manifestPath, JSON.stringify(manifest)); + const arch = os.arch() === "arm64" ? "arm64" : "amd64"; + const { stdout } = await execute(process.execPath, [ + "--import=tsx", + "src/dappnodesdk.ts", + "build", + "--dir", + dir, + "--all-variants", + "--arch", + arch, + "--skip-save" + ]); + expect(stdout).to.include("mainnet, testnet"); + expect(stdout).not.to.include("undefined"); + expect(stdout).to.include("[1/2]").and.include("[2/2]"); + }); + + it("honors --dir in pull-request GitHub action builds", async () => { + const { stdout } = await execute( + process.execPath, + [ + "--import=tsx", + "src/dappnodesdk.ts", + "github-action", + "build", + "--dir", + dir + ], + { + env: { + ...process.env, + GITHUB_TOKEN: "", + GITHUB_EVENT_NAME: "pull_request", + GITHUB_REF: "refs/pull/1/merge", + GITHUB_REPOSITORY: "example/demo" + } + } + ); + expect(stdout).to.include(path.basename(dir).toLowerCase()); + expect(stdout).to.include("[completed]"); + }); + + it("uses the requested native platform for external images", async () => { + const tasks = buildWithCompose({ + architecture: "linux/arm64", + images: [ + { + type: "external", + imageTag: "demo:1", + originalImageTag: "alpine:3.21" + } + ], + compose: { version: "3.5", services: { app: { image: "alpine:3.21" } } }, + manifest: { name: "demo.public.dappnode.eth", version: "0.1.0" }, + destPath: path.join(dir, "image.txz"), + buildTimeout: 3000, + skipSave: true, + rootDir: dir + }); + await new Listr(tasks, { renderer: "silent" }).run(); + expect( + JSON.parse(fs.readFileSync(path.join(dir, "pulls.jsonl"), "utf8").trim()) + ).to.include("--platform=linux/arm64"); + }); +}); diff --git a/test/commands/gaBumpUpstream/format.test.ts b/test/commands/gaBumpUpstream/format.test.ts index c7e0f3f4..deeb2071 100644 --- a/test/commands/gaBumpUpstream/format.test.ts +++ b/test/commands/gaBumpUpstream/format.test.ts @@ -57,6 +57,11 @@ describe("command / gaBumpUpstream / format", () => { "sigp/lighthouse": { newVersion: "v0.1.5", currentVersion: "v0.1.2" + }, + // DAppNodePackage-n8n tracks tags such as n8n@2.46.6 + "n8n-io/n8n": { + newVersion: "n8n@2.46.6", + currentVersion: "n8n@2.46.5" } }; diff --git a/test/commands/init.test.ts b/test/commands/init.test.ts index df2854af..730945b0 100644 --- a/test/commands/init.test.ts +++ b/test/commands/init.test.ts @@ -37,19 +37,19 @@ describe("Init simple package repository", function () { describe("File creation", () => { it("should create a Dockerfile", () => { - expect(testPathExists(dockerfileName)).to.be.true; + expect(testPathExists(dockerfileName)).to.equal(true); }); it("should create a Dappnode manifest", () => { - expect(testPathExists(defaultManifestFileName)).to.be.true; + expect(testPathExists(defaultManifestFileName)).to.equal(true); }); it("should create a docker-compose.yml", () => { - expect(testPathExists("docker-compose.yml")).to.be.true; + expect(testPathExists("docker-compose.yml")).to.equal(true); }); it("should create a .gitignore", () => { - expect(testPathExists(".gitignore")).to.be.true; + expect(testPathExists(".gitignore")).to.equal(true); }); }); @@ -64,8 +64,8 @@ describe("Init simple package repository", function () { it("checks manifest content for correct initialization", () => { const manifestContent = JSON.parse(readTestFile(defaultManifestFileName)); - expect(manifestContent.name).to.exist; - expect(manifestContent.version).to.exist; + expect(manifestContent.name).to.not.equal(undefined); + expect(manifestContent.version).to.not.equal(undefined); }); it("checks compose file for service configuration", () => { @@ -90,7 +90,7 @@ describe("Variant initialization", function () { }); it("should create variant directories", () => { - expect(testPathExists(defaultVariantsDirName)).to.be.true; + expect(testPathExists(defaultVariantsDirName)).to.equal(true); }); it("checks for specific variant manifest", () => { @@ -105,9 +105,9 @@ describe("Variant initialization", function () { const variantManifestContent = JSON.parse( readTestFile(variantManifestPath) ); - expect(rootManifestContent.name).to.not.exist; - expect(variantManifestContent.name).to.exist; - expect(rootManifestContent.version).to.not.exist; - expect(variantManifestContent.version).to.exist; + expect(rootManifestContent.name).to.equal(undefined); + expect(variantManifestContent.name).to.not.equal(undefined); + expect(rootManifestContent.version).to.equal(undefined); + expect(variantManifestContent.version).to.not.equal(undefined); }); }); diff --git a/test/commands/initSafety.test.ts b/test/commands/initSafety.test.ts new file mode 100644 index 00000000..f42e9365 --- /dev/null +++ b/test/commands/initSafety.test.ts @@ -0,0 +1,71 @@ +import fs from "fs"; +import path from "path"; +import { mock } from "node:test"; +import inquirer from "inquirer"; +import { expect } from "chai"; +import { writePackageFiles } from "../../src/commands/init/fileOperations.js"; +import { temporaryDirectory } from "../helpers/fixtures.js"; + +describe("initialization overwrite safety", () => { + let dir: string; + beforeEach(() => { + dir = temporaryDirectory(); + fs.writeFileSync( + path.join(dir, "dappnode_package.json"), + '{"original":true}' + ); + fs.writeFileSync(path.join(dir, "Dockerfile"), "ORIGINAL DOCKERFILE"); + }); + afterEach(() => { + mock.restoreAll(); + fs.rmSync(dir, { recursive: true, force: true }); + }); + + function write(force = false) { + return writePackageFiles({ + dir, + force, + useVariants: false, + answers: { name: "demo.public.dappnode.eth", version: "0.1.0" }, + rootManifest: { name: "demo.public.dappnode.eth", version: "0.1.0" }, + rootCompose: { version: "3.5", services: { app: { build: "." } } }, + composeFileName: "docker-compose.yml", + serviceName: "app" + }); + } + + it("makes no writes while confirmation is pending or after it is declined", async () => { + let answer: (value: { continue: boolean }) => void = () => {}; + mock.method( + inquirer, + "prompt", + () => + new Promise(resolve => { + answer = resolve; + }) + ); + const pending = write(); + expect( + fs.readFileSync(path.join(dir, "dappnode_package.json"), "utf8") + ).to.equal('{"original":true}'); + answer({ continue: false }); + const error = await pending.catch(error => error); + expect(error.message).to.equal("Stopping"); + expect(fs.readFileSync(path.join(dir, "Dockerfile"), "utf8")).to.equal( + "ORIGINAL DOCKERFILE" + ); + }); + + it("preserves an existing Dockerfile when only manifest overwrite is confirmed", async () => { + mock.method(inquirer, "prompt", async () => ({ continue: true })); + await write(); + expect(fs.readFileSync(path.join(dir, "Dockerfile"), "utf8")).to.equal( + "ORIGINAL DOCKERFILE" + ); + expect( + JSON.parse( + fs.readFileSync(path.join(dir, "dappnode_package.json"), "utf8") + ).name + ).to.equal("demo.public.dappnode.eth"); + }); +}); diff --git a/test/files/getRepoSlugFromManifest.test.ts b/test/files/getRepoSlugFromManifest.test.ts new file mode 100644 index 00000000..597609ba --- /dev/null +++ b/test/files/getRepoSlugFromManifest.test.ts @@ -0,0 +1,34 @@ +import { expect } from "chai"; +import { parseGithubRepoSlug } from "../../src/files/manifest/getRepoSlugFromManifest.js"; + +describe("GitHub repository slug from the manifest", () => { + it("accepts the forms used by real package manifests", () => { + for (const url of [ + "https://github.com/dappnode/DAppNodePackage-geth.git", + "git+https://github.com/dappnode/DAppNodePackage-geth.git", + "https://github.com/dappnode/DAppNodePackage-geth", + "git+https://github.com/dappnode/DAppNodePackage-geth", + "https://github.com/dappnode/DAppNodePackage-geth/" + ]) + expect(parseGithubRepoSlug(url), url).to.equal( + "dappnode/DAppNodePackage-geth" + ); + }); + + it("only strips a trailing .git", () => { + expect( + parseGithubRepoSlug("https://github.com/dappnode/tools.github-x") + ).to.equal("dappnode/tools.github-x"); + }); + + it("rejects URLs that merely mention github.com", () => { + for (const url of [ + "https://evil.example/?https://github.com/dappnode/x", + "https://github.com.evil.example/dappnode/x", + "http://github.com/dappnode/x", + "https://github.com/dappnode", + "not a url" + ]) + expect(parseGithubRepoSlug(url), url).to.equal(""); + }); +}); diff --git a/test/files/variantMerge.test.ts b/test/files/variantMerge.test.ts new file mode 100644 index 00000000..3c9dde8c --- /dev/null +++ b/test/files/variantMerge.test.ts @@ -0,0 +1,87 @@ +import fs from "fs"; +import path from "path"; +import yaml from "js-yaml"; +import { expect } from "chai"; +import { readSetupWizardIfExists } from "../../src/files/setupWizard/readSetupWizardIfExists.js"; +import { readNotificationsIfExists } from "../../src/files/notifications/readNotificationsIfExists.js"; +import { temporaryDirectory } from "../helpers/fixtures.js"; + +describe("root and variant config merging", () => { + let root: string; + let variant: string; + beforeEach(() => { + root = temporaryDirectory(); + variant = path.join(root, "package_variants", "mainnet"); + fs.mkdirSync(variant, { recursive: true }); + }); + afterEach(() => fs.rmSync(root, { recursive: true, force: true })); + + it("replaces arrays inside a setup-wizard field instead of merging them by index", () => { + fs.writeFileSync( + path.join(root, "setup-wizard.yml"), + yaml.dump({ + version: "2", + fields: [ + { + id: "network", + title: "Network", + description: "Root description", + enum: ["a", "b", "c"] + } + ] + }) + ); + fs.writeFileSync( + path.join(variant, "setup-wizard.yml"), + yaml.dump({ + version: "2", + fields: [{ id: "network", enum: ["mainnet"] }] + }) + ); + const wizard = readSetupWizardIfExists([{ dir: root }, { dir: variant }]); + expect(wizard?.fields).to.deep.equal([ + { + id: "network", + title: "Network", + description: "Root description", + enum: ["mainnet"] + } + ]); + }); + + it("replaces arrays inside a notification endpoint instead of merging them by index", () => { + const endpoint = { + name: "Health", + enabled: true, + url: "http://pkg.dappnode:8080", + method: "GET", + conditions: ["[STATUS] == 200", "[RESPONSE_TIME] < 500"], + interval: "1m", + group: "pkg", + alerts: [], + definition: { title: "Health", description: "Health check" }, + metric: { min: 0, max: 1, unit: "s" }, + correlationId: "pkg-health", + isBanner: false + }; + fs.writeFileSync( + path.join(root, "notifications.yaml"), + yaml.dump({ endpoints: [endpoint] }) + ); + fs.writeFileSync( + path.join(variant, "notifications.yaml"), + yaml.dump({ + endpoints: [ + { correlationId: "pkg-health", conditions: ["[STATUS] == 204"] } + ] + }) + ); + const notifications = readNotificationsIfExists([ + { dir: root }, + { dir: variant } + ]); + expect(notifications?.endpoints).to.deep.equal([ + { ...endpoint, conditions: ["[STATUS] == 204"] } + ]); + }); +}); diff --git a/test/helpers/fixtures.ts b/test/helpers/fixtures.ts new file mode 100644 index 00000000..c1d5d0eb --- /dev/null +++ b/test/helpers/fixtures.ts @@ -0,0 +1,22 @@ +import fs from "fs"; +import os from "os"; +import path from "path"; + +export function temporaryDirectory(): string { + return fs.mkdtempSync(path.join(os.tmpdir(), "sdk-quality-")); +} + +export function executable(dir: string, name: string, script: string): void { + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(path.join(dir, name), `#!${process.execPath}\n${script}\n`, { + mode: 0o755 + }); +} + +export function useExecutables(dir: string): () => void { + const original = process.env.PATH; + process.env.PATH = `${dir}${path.delimiter}${original || ""}`; + return () => { + process.env.PATH = original; + }; +} diff --git a/test/pinStrategySafety.test.ts b/test/pinStrategySafety.test.ts new file mode 100644 index 00000000..786fcd38 --- /dev/null +++ b/test/pinStrategySafety.test.ts @@ -0,0 +1,166 @@ +import fs from "fs"; +import { execFileSync } from "child_process"; +import path from "path"; +import { mock } from "node:test"; +import { expect } from "chai"; +import Listr from "listr"; +import { fetchPinsWithBranchToDelete } from "../src/pinStrategy/index.js"; +import { PinataPinManager } from "../src/providers/pinata/pinManager.js"; +import { Github } from "../src/providers/github/Github.js"; +import { cleanPinsFromDeletedBranches } from "../src/commands/githubActions/build/cleanPinsFromDeletedBranches.js"; +import { getDeleteOldPinsTask } from "../src/tasks/buildAndUpload/getDeleteOldPinsTask.js"; +import { + executable, + temporaryDirectory, + useExecutables +} from "./helpers/fixtures.js"; + +const manifest = { name: "demo.public.dappnode.eth", version: "0.1.0" }; +describe("safe pin cleanup", () => { + let dir: string; + let restorePath: () => void; + const originalKey = process.env.PINATA_API_KEY; + const originalSecret = process.env.PINATA_SECRET_API_KEY; + beforeEach(() => { + dir = temporaryDirectory(); + fs.writeFileSync( + path.join(dir, "dappnode_package.json"), + JSON.stringify(manifest) + ); + executable( + dir, + "git", + `const args = process.argv.slice(2); if (args[0] === 'merge-base') process.exit(args[2] === '1111111' ? 0 : 1); console.log(args.includes('--abbrev-ref') ? 'feature' : '2222222');` + ); + restorePath = useExecutables(dir); + process.env.PINATA_API_KEY = "fake"; + process.env.PINATA_SECRET_API_KEY = "fake"; + }); + afterEach(() => { + mock.restoreAll(); + restorePath(); + fs.rmSync(dir, { recursive: true, force: true }); + if (originalKey === undefined) delete process.env.PINATA_API_KEY; + else process.env.PINATA_API_KEY = originalKey; + if (originalSecret === undefined) delete process.env.PINATA_SECRET_API_KEY; + else process.env.PINATA_SECRET_API_KEY = originalSecret; + }); + + it("only deletes known ancestor commits, preserving concurrent newer builds", async () => { + const pinata = { + pinList: async () => + ["1111111", "2222222", "3333333", "invalid"].map(commit => ({ + ipfs_pin_hash: commit, + metadata: { keyvalues: { commit } } + })) + } as unknown as PinataPinManager; + const pins = await fetchPinsWithBranchToDelete( + pinata, + manifest, + { branch: "feature", commit: "2222222" }, + dir + ); + expect(pins.map(pin => pin.commit)).to.deep.equal(["1111111"]); + }); + + it("rechecks allegedly deleted branches before unpinning", async () => { + mock.method(Github, "fromLocal", () => ({ + listBranches: async () => [], + branchExists: async (branch: string) => branch === "active" + })); + mock.method(PinataPinManager.prototype, "pinList", async () => + ["active", "removed"].map(branch => ({ + ipfs_pin_hash: branch, + metadata: { keyvalues: { branch, commit: "1111111" } } + })) + ); + const removed: string[] = []; + mock.method(PinataPinManager.prototype, "unpin", async (hash: string) => { + removed.push(hash); + }); + await cleanPinsFromDeletedBranches({ dir }); + expect(removed).to.deep.equal(["removed"]); + }); + + it("does not delete old pins if no replacement was uploaded", async () => { + let lookedUp = false; + mock.method(PinataPinManager.prototype, "pinList", async () => { + lookedUp = true; + return []; + }); + await new Listr( + [ + getDeleteOldPinsTask({ + packagesToBuildProps: [ + { manifest, manifestPaths: [{ dir }] } + ] as never, + deleteOldPins: true, + releaseUploaderProvider: { + network: "ipfs", + type: "pinata", + apiKey: "fake", + secretApiKey: "fake" + } + }) + ], + { renderer: "silent" } + ).run({}); + expect(lookedUp).to.equal(false); + }); +}); + +describe("old pin cleanup on shallow CI checkouts", function () { + this.timeout(30000); + let root: string; + const git = (cwd: string, ...args: string[]): string => + execFileSync( + "git", + ["-c", "commit.gpgsign=false", "-c", "tag.gpgsign=false", ...args], + { + cwd, + encoding: "utf8", + env: { + ...process.env, + GIT_AUTHOR_NAME: "test", + GIT_AUTHOR_EMAIL: "test@example.com", + GIT_COMMITTER_NAME: "test", + GIT_COMMITTER_EMAIL: "test@example.com" + } + } + ).trim(); + + beforeEach(() => (root = temporaryDirectory())); + afterEach(() => fs.rmSync(root, { recursive: true, force: true })); + + it("fetches missing history so ancestor pins are deleted, never unknown ones", async () => { + const origin = path.join(root, "origin"); + fs.mkdirSync(origin); + git(origin, "init", "--quiet", "--initial-branch=feature"); + const commits: string[] = []; + for (const n of [1, 2, 3]) { + fs.writeFileSync(path.join(origin, "file"), String(n)); + git(origin, "add", "file"); + git(origin, "commit", "--quiet", "-m", `commit ${n}`); + commits.push(git(origin, "rev-parse", "HEAD")); + } + const clone = path.join(root, "clone"); + git(root, "clone", "--quiet", "--depth=1", `file://${origin}`, clone); + expect(git(clone, "rev-parse", "--is-shallow-repository")).to.equal("true"); + + const foreign = "f".repeat(40); + const pinata = { + pinList: async () => + [...commits, foreign].map(commit => ({ + ipfs_pin_hash: commit, + metadata: { keyvalues: { commit } } + })) + } as unknown as PinataPinManager; + const pins = await fetchPinsWithBranchToDelete( + pinata, + manifest, + { branch: "feature", commit: commits[2] }, + clone + ); + expect(pins.map(pin => pin.commit)).to.deep.equal(commits.slice(0, 2)); + }); +}); diff --git a/test/providers/apm/ApmRepository.test.ts b/test/providers/apm/ApmRepository.test.ts new file mode 100644 index 00000000..54b75315 --- /dev/null +++ b/test/providers/apm/ApmRepository.test.ts @@ -0,0 +1,143 @@ +import { mock } from "node:test"; +import registryAbi from "../../../src/contracts/ApmRegistryAbi.json" with { type: "json" }; +import { + Contract, + Interface, + JsonRpcProvider, + toUtf8Bytes, + hexlify, + type TransactionRequest +} from "ethers"; +import { expect } from "chai"; +import { ApmRepository } from "../../../src/providers/apm/ApmRepository.js"; +import { buildTxData } from "../../../src/tasks/generatePublishTxs/index.js"; +import abi from "../../../src/contracts/RepoAbi.json" with { type: "json" }; + +const address = "0x0000000000000000000000000000000000001234"; +class LocalProvider extends JsonRpcProvider { + constructor(private readonly registered = true) { + super("http://unused", 1, { staticNetwork: true }); + } + async resolveName(): Promise { + return this.registered ? address : null; + } + async call(tx: TransactionRequest): Promise { + const contract = new Interface(abi); + expect(tx.to).to.equal(address); + expect(tx.data).to.equal(contract.encodeFunctionData("getLatest")); + return contract.encodeFunctionResult("getLatest", [ + [1, 2, 3], + address, + hexlify(toUtf8Bytes("/ipfs/QmLatest")) + ]); + } +} + +describe("minimal APM client", () => { + it("resolves ENS and decodes the existing contract ABI", async () => { + const provider = new LocalProvider(); + try { + const client = new ApmRepository("http://unused", provider); + expect( + await client.getVersionAndIpfsHash({ + dnpNameOrHash: "demo.public.dappnode.eth" + }) + ).to.deep.equal({ version: "1.2.3", contentUri: "/ipfs/QmLatest" }); + expect( + await client.getRepoContract("demo.public.dappnode.eth") + ).to.be.instanceOf(Contract); + } finally { + provider.destroy(); + } + }); + + it("preserves new-repository detection", async () => { + const provider = new LocalProvider(false); + try { + const error = await new ApmRepository("http://unused", provider) + .getRepoContract("new.public.dappnode.eth") + .catch(error => error); + expect(error.message).to.include("NOREPO"); + } finally { + provider.destroy(); + } + }); + + it("generates an existing-repository transaction without a live RPC", async () => { + const provider = new LocalProvider(); + try { + const result = await buildTxData({ + apm: new ApmRepository("http://unused", provider), + contractAddress: address, + dnpName: "demo.public.dappnode.eth", + version: "1.2.4", + releaseMultiHash: "/ipfs/QmNext", + developerAddress: address, + ethereumUrl: "http://unused" + }); + const decoded = new Interface(abi).decodeFunctionData( + "newVersion", + result.data + ); + expect(result.to).to.equal(address); + expect([...decoded[0]]).to.deep.equal([1n, 2n, 4n]); + expect(decoded[2]).to.equal(hexlify(toUtf8Bytes("/ipfs/QmNext"))); + } finally { + provider.destroy(); + } + }); + it("generates a new-repository transaction after an unresolved package name", async () => { + const provider = new LocalProvider(false); + const registry = "0x0000000000000000000000000000000000005678"; + const resolution = mock.method( + JsonRpcProvider.prototype, + "resolveName", + async () => registry + ); + try { + const result = await buildTxData({ + apm: new ApmRepository("http://unused", provider), + contractAddress: address, + dnpName: "new.public.dappnode.eth", + version: "0.1.0", + releaseMultiHash: "/ipfs/QmNew", + developerAddress: address, + ethereumUrl: "http://unused" + }); + const decoded = new Interface(registryAbi).decodeFunctionData( + "newRepoWithVersion", + result.data + ); + expect(result.to).to.equal(registry); + expect(decoded[0]).to.equal("new"); + expect(decoded[1]).to.equal(address); + expect([...decoded[2]]).to.deep.equal([0n, 1n, 0n]); + } finally { + resolution.mock.restore(); + provider.destroy(); + } + }); + + it("propagates RPC failures instead of treating them as an unpublished package", async () => { + const provider = new LocalProvider(); + const rpcFailure = new Error("RPC timeout"); + const resolution = mock.method(provider, "resolveName", async () => { + throw rpcFailure; + }); + try { + const error = await buildTxData({ + apm: new ApmRepository("http://unused", provider), + contractAddress: address, + dnpName: "demo.public.dappnode.eth", + version: "0.1.0", + releaseMultiHash: "/ipfs/QmNew", + developerAddress: address, + ethereumUrl: "http://unused" + }).catch(error => error); + expect(error).to.equal(rpcFailure); + } finally { + resolution.mock.restore(); + provider.destroy(); + } + }); +}); diff --git a/test/providers/github/pagination.test.ts b/test/providers/github/pagination.test.ts new file mode 100644 index 00000000..1e595833 --- /dev/null +++ b/test/providers/github/pagination.test.ts @@ -0,0 +1,31 @@ +import { expect } from "chai"; +import { Github } from "../../../src/providers/github/Github.js"; + +describe("GitHub branch pagination", () => { + it("uses the paginator so cleanup sees branches after the first page", async () => { + const original = process.env.GITHUB_TOKEN; + process.env.GITHUB_TOKEN = "test-token"; + try { + const github = new Github({ owner: "example", repo: "demo" }); + const branches = Array.from({ length: 135 }, (_, index) => ({ + name: `branch-${index}` + })); + const listBranches = () => {}; + let called = false; + (github as unknown as { octokit: unknown }).octokit = { + rest: { repos: { listBranches } }, + paginate: async (method: unknown, parameters: { per_page: number }) => { + expect(method).to.equal(listBranches); + expect(parameters.per_page).to.equal(100); + called = true; + return branches; + } + }; + expect(await github.listBranches()).to.have.length(135); + expect(called).to.equal(true); + } finally { + if (original === undefined) delete process.env.GITHUB_TOKEN; + else process.env.GITHUB_TOKEN = original; + } + }); +}); diff --git a/test/providers/github/uploadReleaseAssets.test.ts b/test/providers/github/uploadReleaseAssets.test.ts new file mode 100644 index 00000000..81bbf84e --- /dev/null +++ b/test/providers/github/uploadReleaseAssets.test.ts @@ -0,0 +1,116 @@ +import fs from "fs"; +import path from "path"; +import { mock } from "node:test"; +import { expect } from "chai"; +import { Github } from "../../../src/providers/github/Github.js"; +import { temporaryDirectory } from "../../helpers/fixtures.js"; + +const alreadyExists = Object.assign(new Error("Validation Failed"), { + status: 422, + response: { + data: { errors: [{ resource: "ReleaseAsset", code: "already_exists" }] } + } +}); + +function githubWith(octokit: unknown): Github { + const original = process.env.GITHUB_TOKEN; + process.env.GITHUB_TOKEN = "fake"; + const github = new Github({ owner: "dappnode", repo: "demo" }); + if (original === undefined) delete process.env.GITHUB_TOKEN; + else process.env.GITHUB_TOKEN = original; + (github as unknown as { octokit: unknown }).octokit = octokit; + return github; +} + +describe("idempotent GitHub release asset upload", function () { + this.timeout(30000); // async-retry backs off ~7s across its 3 retries + let dir: string; + beforeEach(() => { + dir = temporaryDirectory(); + fs.writeFileSync(path.join(dir, "image.txz"), "12345"); + }); + afterEach(() => fs.rmSync(dir, { recursive: true, force: true })); + + it("accepts an asset a failed attempt already stored completely", async () => { + let posts = 0; + const github = githubWith({ + request: async () => { + posts++; + throw alreadyExists; + }, + paginate: async () => [ + { id: 7, name: "image.txz", size: 5, state: "uploaded" } + ], + rest: { repos: { listReleaseAssets: {}, deleteReleaseAsset: {} } } + }); + await github.uploadReleaseAssets({ releaseId: 1, assetsDir: dir }); + expect(posts).to.equal(1); + }); + + it("replaces a partial asset and uploads again", async () => { + const calls: string[] = []; + const github = githubWith({ + request: async () => { + calls.push("post"); + if (calls.filter(call => call === "post").length === 1) + throw alreadyExists; + }, + paginate: async () => [ + { id: 7, name: "image.txz", size: 2, state: "uploaded" } + ], + rest: { + repos: { + listReleaseAssets: {}, + deleteReleaseAsset: async ({ asset_id }: { asset_id: number }) => { + calls.push(`delete:${asset_id}`); + } + } + } + }); + await github.uploadReleaseAssets({ releaseId: 1, assetsDir: dir }); + expect(calls).to.deep.equal(["post", "delete:7", "post"]); + }); + + it("closes the file stream of every attempt, including failed ones", async () => { + const streams: fs.ReadStream[] = []; + const original = fs.createReadStream; + mock.method( + fs, + "createReadStream", + (...args: Parameters) => { + const stream = original(...args); + streams.push(stream); + return stream; + } + ); + let posts = 0; + const github = githubWith({ + request: async () => { + if (++posts === 1) + throw Object.assign(new Error("reset"), { status: 502 }); + } + }); + try { + await github.uploadReleaseAssets({ releaseId: 1, assetsDir: dir }); + } finally { + mock.restoreAll(); + } + expect(streams).to.have.length(2); + expect(streams.every(stream => stream.destroyed)).to.equal(true); + // Removing the file while a stream of a failed attempt is still opening must not crash. + fs.rmSync(dir, { recursive: true, force: true }); + await new Promise(resolve => setTimeout(resolve, 50)); + }); + + it("still fails on other errors", async () => { + const github = githubWith({ + request: async () => { + throw Object.assign(new Error("Bad credentials"), { status: 401 }); + } + }); + const error = await github + .uploadReleaseAssets({ releaseId: 1, assetsDir: dir }) + .catch(error => error); + expect(error.message).to.include("Bad credentials"); + }); +}); diff --git a/test/tasks/buildAndUpload/packageArtifacts.test.ts b/test/tasks/buildAndUpload/packageArtifacts.test.ts new file mode 100644 index 00000000..26c1bfde --- /dev/null +++ b/test/tasks/buildAndUpload/packageArtifacts.test.ts @@ -0,0 +1,235 @@ +import fs from "fs"; +import path from "path"; +import yaml from "js-yaml"; +import { expect } from "chai"; +import Listr from "listr"; +import { initHandler } from "../../../src/commands/init/handler.js"; +import { generatePackagesProps } from "../../../src/tasks/buildAndUpload/generatePackagesProps.js"; +import { getFileCopyTask } from "../../../src/tasks/buildAndUpload/getFileCopyTask.js"; +import { getFileValidationTask } from "../../../src/tasks/buildAndUpload/getFileValidationTask.js"; +import { getUpdateFilesTask } from "../../../src/tasks/publish/subtasks/getUpdateFilesTask.js"; +import { + readManifest, + readSetupWizardIfExists +} from "../../../src/files/index.js"; +import { ManifestFormat } from "../../../src/files/manifest/types.js"; +import { + temporaryDirectory, + executable, + useExecutables +} from "../../helpers/fixtures.js"; + +describe("template and generic package artifacts", () => { + let dir: string; + let variantsDirPath: string; + beforeEach(async () => { + dir = temporaryDirectory(); + await initHandler({ dir, yes: true, force: true, use_variants: true }); + variantsDirPath = path.join(dir, "package_variants"); + }); + afterEach(() => fs.rmSync(dir, { recursive: true, force: true })); + + it("packages the merged wizard and notifications, with variant asset overrides", async () => { + const variantDir = path.join(variantsDirPath, "mainnet"); + fs.writeFileSync( + path.join(dir, "setup-wizard.json"), + JSON.stringify({ + version: "2", + fields: [ + { id: "shared", title: "Shared", description: "Shared field" }, + { id: "replace", title: "Old", description: "Preserved description" } + ] + }) + ); + fs.writeFileSync( + path.join(variantDir, "setup-wizard.yaml"), + yaml.dump({ + version: "2", + fields: [ + { id: "replace", title: "Variant" }, + { id: "new", title: "New", description: "New field" } + ] + }) + ); + fs.writeFileSync( + path.join(dir, "notifications.yaml"), + yaml.dump({ + customEndpoints: [ + { + name: "shared", + correlationId: "shared", + description: "shared", + enabled: true, + isBanner: false + } + ] + }) + ); + fs.writeFileSync( + path.join(variantDir, "notifications.yaml"), + yaml.dump({ + customEndpoints: [ + { + name: "variant", + correlationId: "variant", + description: "variant", + enabled: true, + isBanner: false + } + ] + }) + ); + fs.writeFileSync(path.join(dir, "disclaimer.md"), "shared disclaimer"); + fs.writeFileSync( + path.join(variantDir, "disclaimer.md"), + "variant disclaimer" + ); + fs.writeFileSync( + path.join(dir, "prometheus-targets.json"), + JSON.stringify([ + { targets: ["shared:9090"], labels: { network: "shared" } } + ]) + ); + fs.writeFileSync( + path.join(variantDir, "prometheus-targets.yaml"), + yaml.dump([{ targets: ["variant:9090"], labels: { network: "variant" } }]) + ); + const packages = generatePackagesProps({ + variants: ["mainnet"], + rootDir: dir, + variantsDirPath + }); + const pkg = packages[0]; + fs.mkdirSync(pkg.releaseDir, { recursive: true }); + await new Listr( + [ + getFileCopyTask({ + packagesToBuildProps: packages, + rootDir: dir, + variantsDirPath, + composeFileName: "docker-compose.yml" + }) + ], + { renderer: "silent" } + ).run(); + // The variant's targets replace the root's (e.g. a stale root template in + // erigon-generic must not be scraped); YAML sources are released as JSON. + expect( + JSON.parse( + fs.readFileSync( + path.join(pkg.releaseDir, "prometheus-targets.json"), + "utf8" + ) + ) + ).to.deep.equal([ + { targets: ["variant:9090"], labels: { network: "variant" } } + ]); + const wizard = JSON.parse( + fs.readFileSync(path.join(pkg.releaseDir, "setup-wizard.json"), "utf8") + ); + expect( + wizard.fields.map((field: { id: string }) => field.id) + ).to.deep.equal(["shared", "replace", "new"]); + expect(wizard.fields[1]).to.include({ + title: "Variant", + description: "Preserved description" + }); + expect( + yaml.load( + fs.readFileSync(path.join(pkg.releaseDir, "notifications.yaml"), "utf8") + ) + ).to.deep.equal(pkg.notifications); + expect( + fs.readFileSync(path.join(pkg.releaseDir, "disclaimer.md"), "utf8") + ).to.equal("variant disclaimer"); + }); + + it("preserves an upstream image and updates the release directory when publishing", async () => { + const packages = generatePackagesProps({ + variants: ["mainnet"], + rootDir: dir, + variantsDirPath + }); + const pkg = packages[0]; + const composePath = path.join( + variantsDirPath, + "mainnet", + "docker-compose.yml" + ); + fs.writeFileSync( + composePath, + yaml.dump({ + version: "3.5", + services: { external: { image: "alpine:3.21" } } + }) + ); + const ctx = { + [pkg.manifest.name]: { + nextVersion: "0.1.2", + releaseDir: pkg.releaseDir, + variant: pkg.variant + } + }; + await new Listr( + [ + getUpdateFilesTask({ + rootDir: dir, + variantsDirPath, + composeFileName: "docker-compose.yml", + packagesToBuildProps: packages + }) + ], + { renderer: "silent" } + ).run(ctx); + expect(pkg.images.find(image => image.type === "external")).to.include({ + originalImageTag: "alpine:3.21" + }); + expect(pkg.manifest.version).to.equal("0.1.2"); + expect(pkg.releaseDir).to.equal( + path.join(dir, `build_${pkg.manifest.name}_0.1.2`) + ); + expect(ctx[pkg.manifest.name].releaseDir).to.equal(pkg.releaseDir); + }); + + it("accepts a single YAML manifest without invoking template-only restrictions", () => { + const file = path.join(dir, "single.yaml"); + fs.writeFileSync(file, "name: demo.public.dappnode.eth\nversion: 0.1.0\n"); + expect( + readManifest([{ dir, manifestFileName: "single.yaml" }]).format + ).to.equal(ManifestFormat.yaml); + }); + + it("accepts JSON setup wizards and rejects invalid wizard schemas", async () => { + fs.writeFileSync( + path.join(dir, "setup-wizard.json"), + '{"version":"2","fields":[]}' + ); + expect(readSetupWizardIfExists([{ dir }])).to.deep.equal({ + version: "2", + fields: [] + }); + const packages = generatePackagesProps({ + variants: ["mainnet"], + rootDir: dir, + variantsDirPath + }); + packages[0].setupWizard = { + version: "2", + fields: [{ id: "missing-title" }] + } as never; + const bin = path.join(dir, "bin"); + executable(bin, "docker", "process.exit(0);"); + const restore = useExecutables(bin); + try { + const error = await new Listr( + [getFileValidationTask({ packagesToBuildProps: packages })], + { renderer: "silent" } + ) + .run() + .catch(error => error); + expect(error.message).to.include("Invalid setupWizard"); + } finally { + restore(); + } + }); +}); diff --git a/test/tasks/buildAndUpload/validationCoercion.test.ts b/test/tasks/buildAndUpload/validationCoercion.test.ts new file mode 100644 index 00000000..8187002b --- /dev/null +++ b/test/tasks/buildAndUpload/validationCoercion.test.ts @@ -0,0 +1,53 @@ +import { expect } from "chai"; +import { validateNotificationsSchema } from "@dappnode/schemas"; +import { validateReportingCoercions } from "../../../src/tasks/buildAndUpload/getFileValidationTask.js"; + +describe("schema coercion warnings", () => { + it("reports values the schema validator coerced in place", () => { + // DAppNodePackage-DMS ships `isBanner: "false"`, a truthy string for consumers. + const notifications = { + endpoints: [ + { + name: "Health", + enabled: true, + url: "http://pkg.dappnode:8080", + method: "GET", + conditions: ["[STATUS] == 200"], + interval: "1m", + group: "pkg", + priority: "medium", + alerts: [ + { + type: "custom", + enabled: true, + description: "Health failed", + "failure-threshold": 2, + "success-threshold": 1, + "send-on-resolved": true + } + ], + definition: { title: "Health", description: "Health check" }, + metric: { min: 0, max: 1, unit: "s" }, + correlationId: "pkg-health", + isBanner: "false" + } + ] + }; + const changes = validateReportingCoercions( + "pkg notifications", + notifications as never, + validateNotificationsSchema + ); + expect(notifications.endpoints[0].isBanner).to.equal(false); + expect(changes).to.deep.equal([ + 'pkg notifications endpoints.0.isBanner: "false" -> false' + ]); + }); + + it("reports nothing when the source is already well typed", () => { + const wizard = { version: "2", fields: [] }; + expect( + validateReportingCoercions("pkg wizard", wizard, () => undefined) + ).to.deep.equal([]); + }); +}); diff --git a/test/tasks/generatePublishTx.test.ts b/test/tasks/generatePublishTx.test.ts index dbce6e73..b7b3481b 100644 --- a/test/tasks/generatePublishTx.test.ts +++ b/test/tasks/generatePublishTx.test.ts @@ -4,7 +4,7 @@ import { buildTxData } from "../../src/tasks/generatePublishTxs/index.js"; import { writeManifest } from "../../src/files/index.js"; import { testDir, cleanTestDir } from "../testUtils.js"; import { getEthereumUrl } from "../../src/utils/getEthereumUrl.js"; -import { ApmRepository } from "@dappnode/toolkit"; +import { ApmRepository } from "../../src/providers/apm/ApmRepository.js"; // This test will create the following fake files // ./dappnode_package.json => fake manifest @@ -48,8 +48,7 @@ describe("generatePublishTx", async function () { expect(txData).to.deep.equal({ to: "0xEe66C4765696C922078e8670aA9E6d4F6fFcc455", // admin.dnp.dappnode.eth resolves to this address value: 0, - data: - "0x73053410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000082f697066732f516d000000000000000000000000000000000000000000000000", + data: "0x73053410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000082f697066732f516d000000000000000000000000000000000000000000000000", gasLimit: 300000, ensName: name, currentVersion: version, @@ -81,8 +80,7 @@ describe("generatePublishTx", async function () { expect(txData).to.deep.equal({ to: "0x266BFdb2124A68beB6769dC887BD655f78778923", // Registry contract address value: 0, - data: - "0x32ab6af000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000086e65772d7265706f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082f697066732f516d000000000000000000000000000000000000000000000000", + data: "0x32ab6af000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000086e65772d7265706f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082f697066732f516d000000000000000000000000000000000000000000000000", gasLimit: 1100000, ensName: name, currentVersion: version, diff --git a/test/tasks/inspectImageForPlatform.test.ts b/test/tasks/inspectImageForPlatform.test.ts new file mode 100644 index 00000000..f09ec6c6 --- /dev/null +++ b/test/tasks/inspectImageForPlatform.test.ts @@ -0,0 +1,62 @@ +import fs from "fs"; +import { expect } from "chai"; +import { inspectImageForPlatform } from "../../src/tasks/saveAndCompressImages.js"; +import { + executable, + temporaryDirectory, + useExecutables +} from "../helpers/fixtures.js"; + +describe("platform-specific image inspection", () => { + let dir: string; + let restorePath: () => void; + beforeEach(() => { + dir = temporaryDirectory(); + restorePath = useExecutables(dir); + }); + afterEach(() => { + restorePath(); + fs.rmSync(dir, { recursive: true, force: true }); + }); + + it("selects the requested platform (containerd store holds several per tag)", async () => { + executable( + dir, + "docker", + `const p = process.argv.find(a => a.startsWith("--platform=")); + console.log(JSON.stringify([{ Os: "linux", Architecture: p ? p.split("/")[1] : "arm64" }]));` + ); + const data = JSON.parse( + await inspectImageForPlatform("demo:1", "linux/amd64") + ); + expect(data[0].Architecture).to.equal("amd64"); + }); + + it("falls back to a plain inspect on Docker CLI versions without --platform", async () => { + executable( + dir, + "docker", + `if (process.argv.some(a => a.startsWith("--platform"))) { + process.stderr.write("unknown flag: --platform\\nSee 'docker image inspect --help'."); + process.exit(125); + } + console.log(JSON.stringify([{ Os: "linux", Architecture: "amd64" }]));` + ); + const data = JSON.parse( + await inspectImageForPlatform("demo:1", "linux/amd64") + ); + expect(data[0].Architecture).to.equal("amd64"); + }); + + it("does not hide other inspect failures", async () => { + executable( + dir, + "docker", + `process.stderr.write("No such image: demo:1"); process.exit(1);` + ); + const error = await inspectImageForPlatform("demo:1", "linux/amd64").catch( + error => error + ); + expect(error.message).to.include("No such image"); + }); +}); diff --git a/test/tasks/releaseAssets.test.ts b/test/tasks/releaseAssets.test.ts new file mode 100644 index 00000000..69e8ce2d --- /dev/null +++ b/test/tasks/releaseAssets.test.ts @@ -0,0 +1,96 @@ +import fs from "fs"; +import path from "path"; +import { expect } from "chai"; +import Listr from "listr"; +import { getCreateReleaseTask } from "../../src/tasks/createGithubRelease/subtasks/getCreateReleaseTask.js"; +import { Github } from "../../src/providers/github/Github.js"; +import type { ListrContextPublish } from "../../src/types.js"; +import { temporaryDirectory } from "../helpers/fixtures.js"; + +describe("complete GitHub releases", () => { + let dir: string; + let ctx: ListrContextPublish; + beforeEach(() => { + dir = temporaryDirectory(); + fs.writeFileSync( + path.join(dir, "dappnode_package.json"), + '{"name":"demo.public.dappnode.eth","version":"0.1.0"}' + ); + fs.writeFileSync( + path.join(dir, "docker-compose.yml"), + 'version: "3.5"\nservices:\n app:\n image: demo:1\n' + ); + for (const name of [ + "setup-wizard.json", + "setup.schema.json", + "setup-ui.json", + "dashboard-grafana-dashboard.json" + ]) + fs.writeFileSync(path.join(dir, name), "{}"); + fs.writeFileSync(path.join(dir, "avatar.png"), "avatar"); + fs.writeFileSync(path.join(dir, "image.txz"), "image"); + ctx = { + "demo.public.dappnode.eth": { + variant: null, + releaseDir: dir, + nextVersion: "0.1.0", + releaseMultiHash: "/ipfs/QmTest", + txData: { + to: "0x0000000000000000000000000000000000001234", + value: 0, + data: "0x", + gasLimit: 300000, + ensName: "demo.public.dappnode.eth", + currentVersion: "0.1.0", + releaseMultiHash: "/ipfs/QmTest" + } + } + }; + }); + afterEach(() => fs.rmSync(dir, { recursive: true, force: true })); + + it("includes every defined optional release artifact", async () => { + const uploaded: string[] = []; + const github = { + deleteReleaseAndAssets: async () => {}, + createRelease: async () => 1, + uploadReleaseAssets: async ({ + matchPattern + }: { + matchPattern: RegExp; + }) => { + uploaded.push( + ...fs.readdirSync(dir).filter(file => matchPattern.test(file)) + ); + } + } as unknown as Github; + await new Listr([getCreateReleaseTask({ github, isMultiVariant: false })], { + renderer: "silent" + }).run(ctx); + expect(uploaded).to.include.members([ + "setup-wizard.json", + "setup.schema.json", + "setup-ui.json", + "dashboard-grafana-dashboard.json", + "image.txz", + "avatar.png" + ]); + }); + + it("fails the release when asset upload fails", async () => { + const github = { + deleteReleaseAndAssets: async () => {}, + createRelease: async () => 1, + uploadReleaseAssets: async () => { + throw new Error("upload failed"); + } + } as unknown as Github; + const error = await new Listr( + [getCreateReleaseTask({ github, isMultiVariant: false })], + { renderer: "silent" } + ) + .run(ctx) + .catch(error => error); + expect(error.message).to.equal("upload failed"); + }); +}); diff --git a/test/tasks/saveAndCompressImages.test.ts b/test/tasks/saveAndCompressImages.test.ts new file mode 100644 index 00000000..987d380c --- /dev/null +++ b/test/tasks/saveAndCompressImages.test.ts @@ -0,0 +1,102 @@ +import fs from "fs"; +import path from "path"; +import { expect } from "chai"; +import { saveAndCompressImages } from "../../src/tasks/saveAndCompressImages.js"; +import { + executable, + temporaryDirectory, + useExecutables +} from "../helpers/fixtures.js"; + +describe("atomic image export", function () { + this.timeout(10000); + let dir: string; + let restorePath: () => void; + let destPath: string; + + beforeEach(() => { + dir = temporaryDirectory(); + destPath = path.join(dir, "image.txz"); + fs.writeFileSync(destPath, "previous verified archive"); + executable( + dir, + "xz", + 'process.on("SIGALRM", () => {}); process.stdin.pipe(process.stdout);' + ); + restorePath = useExecutables(dir); + }); + afterEach(() => { + restorePath(); + fs.rmSync(dir, { recursive: true, force: true }); + }); + + it("rejects a failed docker save and preserves the previous archive", async () => { + executable( + dir, + "docker", + 'process.stderr.write("daemon export failed"); process.exit(42);' + ); + const error = await saveAndCompressImages({ + imageTags: ["demo:1"], + destPath, + timeout: 3000 + }).catch(error => error); + expect(error).to.be.instanceOf(Error); + expect(error.message) + .to.include("docker save failed") + .and.include("daemon export failed"); + expect(fs.readFileSync(destPath, "utf8")).to.equal( + "previous verified archive" + ); + expect( + fs.readdirSync(dir).some(file => file.startsWith(".dappnodesdk-")) + ).to.equal(false); + }); + + it("rejects signal termination of the compressor", async () => { + executable(dir, "docker", 'process.stdout.write("tar payload");'); + executable( + dir, + "xz", + 'process.stdin.resume(); process.kill(process.pid, "SIGTERM");' + ); + const error = await saveAndCompressImages({ + imageTags: ["demo:1"], + destPath, + timeout: 3000 + }).catch(error => error); + expect(error).to.be.instanceOf(Error); + expect(fs.readFileSync(destPath, "utf8")).to.equal( + "previous verified archive" + ); + }); + + it("times out and cancels both child processes", async () => { + executable(dir, "docker", "setInterval(() => {}, 1000);"); + const error = await saveAndCompressImages({ + imageTags: ["demo:1"], + destPath, + timeout: 100 + }).catch(error => error); + expect(error.message).to.include("timed out"); + expect(fs.readFileSync(destPath, "utf8")).to.equal( + "previous verified archive" + ); + }); + + it("waits for all output before replacing the archive", async () => { + executable( + dir, + "docker", + "process.stdout.write(Buffer.alloc(2 * 1024 * 1024, 7));" + ); + await saveAndCompressImages({ + imageTags: ["demo:1"], + destPath, + timeout: 3000 + }); + const data = fs.readFileSync(destPath); + expect(data.length).to.equal(2 * 1024 * 1024); + expect(data.every(byte => byte === 7)).to.equal(true); + }); +}); diff --git a/test/tasks/uploadProgress.test.ts b/test/tasks/uploadProgress.test.ts new file mode 100644 index 00000000..a3b8697c --- /dev/null +++ b/test/tasks/uploadProgress.test.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import http from "http"; +import { expect } from "chai"; +import { pinataAddFromFs } from "../../src/releaseUploader/pinata/addDirFromFs.js"; +import { swarmAddDirFromFs } from "../../src/releaseUploader/swarmNode/addDirFromFs.js"; +import { ipfsAddDirFromUrls } from "../../src/releaseUploader/ipfsNode/addDirFromUrls.js"; +import { temporaryDirectory } from "../helpers/fixtures.js"; + +describe("local upload transport and progress", function () { + this.timeout(10000); + let dir: string; + let server: http.Server; + let url: string; + let route: ( + request: http.IncomingMessage, + response: http.ServerResponse + ) => void; + beforeEach(async () => { + dir = temporaryDirectory(); + fs.writeFileSync(path.join(dir, "image.txz"), Buffer.alloc(1024 * 1024, 7)); + server = http.createServer((request, response) => route(request, response)); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); + }); + const address = server.address(); + if (!address || typeof address === "string") + throw new Error("No server address"); + url = `http://127.0.0.1:${address.port}`; + }); + afterEach(async () => { + server?.closeAllConnections(); + await new Promise(resolve => server?.close(() => resolve())); + fs.rmSync(dir, { recursive: true, force: true }); + }); + + it("changes to pinning confirmation after transmission, before the response", async () => { + let confirmed = false; + let sent = false; + const events: string[] = []; + route = (request, response) => { + expect(request.url).to.equal("/pinning/pinFileToIPFS"); + request.resume(); + request.on("end", () => + setTimeout(() => { + expect(sent).to.equal(true); + confirmed = true; + response.setHeader("content-type", "application/json"); + response.end('{"IpfsHash":"QmTest"}'); + }, 100) + ); + }; + const hash = await pinataAddFromFs({ + dirOrFilePath: dir, + pinataUrl: url, + credentials: { apiKey: "fake", secretApiKey: "fake" }, + onProgress: percent => events.push(`bytes:${percent}`), + onUploadComplete: () => { + sent = true; + expect(confirmed).to.equal(false); + events.push("pinning"); + } + }); + expect(hash).to.equal("/ipfs/QmTest"); + expect(events.at(-1)).to.equal("pinning"); + }); + + it("posts Swarm archives using a relative path under prefixUrl", async () => { + route = (request, response) => { + expect(request.url).to.equal("/bzz:/"); + request.resume(); + request.on("end", () => response.end("swarm-hash")); + }; + expect(await swarmAddDirFromFs(dir, url)).to.equal("/bzz/swarm-hash"); + }); + + it("streams GitHub-style downloads through got into the IPFS upload", async () => { + let upload = ""; + route = (request, response) => { + if (request.url === "/asset") { + response.end("downloaded contents"); + return; + } + expect(request.url).to.equal("/api/v0/add"); + request.setEncoding("utf8"); + request.on("data", chunk => { + upload += chunk; + }); + request.on("end", () => + response.end('{"Name":"release","Hash":"QmDownloaded"}\n') + ); + }; + expect( + await ipfsAddDirFromUrls( + [{ filepath: "release/file.txt", url: `${url}/asset` }], + url + ) + ).to.equal("/ipfs/QmDownloaded"); + expect(upload) + .to.include("downloaded contents") + .and.include("release/file.txt"); + }); + + it("rejects HTTP failures during downloads instead of uploading an error page", async () => { + route = (request, response) => { + if (request.url === "/missing") { + response.writeHead(404); + response.end("missing"); + return; + } + request.resume(); + }; + const error = await ipfsAddDirFromUrls( + [{ filepath: "release/file.txt", url: `${url}/missing` }], + url + ).catch(error => error); + expect(error).to.be.instanceOf(Error); + expect(error.message).to.include("404"); + }); +}); diff --git a/test/testUtils.ts b/test/testUtils.ts index 6f752090..198f520d 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -1,11 +1,10 @@ import fs from "fs"; -import rimraf from "rimraf"; import { Compose, Manifest, getImageTag } from "@dappnode/types"; import path from "path"; export const testDir = "test_files"; export function cleanTestDir(): void { - rimraf.sync(testDir); + fs.rmSync(testDir, { recursive: true, force: true }); fs.mkdirSync(testDir, { recursive: true }); } diff --git a/test/utils/formatCliError.test.ts b/test/utils/formatCliError.test.ts new file mode 100644 index 00000000..27ecea74 --- /dev/null +++ b/test/utils/formatCliError.test.ts @@ -0,0 +1,46 @@ +import { expect } from "chai"; +import { stripVTControlCharacters } from "util"; +import { formatCliError } from "../../src/utils/formatCliError.js"; +import { shell } from "../../src/utils/shell.js"; + +const plain = (text: string) => stripVTControlCharacters(text); + +describe("CLI error output", () => { + const failing = (onData?: (line: string) => void) => + shell(["sh", "-c", "echo building; echo 'ERROR: boom' >&2; exit 1"], { + onData + }).catch(e => e); + + it("prints a failed command once, with the end of its output", async () => { + const output = plain( + formatCliError(await failing(), { outputStreamed: false }) + ); + expect(output).to.equal( + "✖ Command failed (exit 1): sh -c echo building; echo 'ERROR: boom' >&2; exit 1\n ERROR: boom" + ); + }); + + it("prints only the summary when the log was already streamed", async () => { + const error = await failing(() => {}); + expect(plain(formatCliError(error, { outputStreamed: true }))).to.equal( + "✖ Command failed (exit 1): sh -c echo building; echo 'ERROR: boom' >&2; exit 1" + ); + // The terminal renderer only previews a few lines, so the output tail is still shown there. + expect(plain(formatCliError(error, { outputStreamed: false }))).to.include( + "ERROR: boom" + ); + }); + + it("prints other errors by message, and the stack only with --debug", () => { + const error = new Error("Invalid compose:\ninvalid containerPort: 70007"); + expect(plain(formatCliError(error, { outputStreamed: false }))).to.equal( + "✖ Invalid compose:\n invalid containerPort: 70007" + ); + const debugOutput = plain( + formatCliError(error, { debug: true, outputStreamed: false }) + ); + expect(debugOutput).to.include(" at "); + // The message is not repeated through the stack header. + expect(debugOutput.match(/invalid containerPort/g)).to.have.length(1); + }); +}); diff --git a/test/utils/process.test.ts b/test/utils/process.test.ts new file mode 100644 index 00000000..a7534150 --- /dev/null +++ b/test/utils/process.test.ts @@ -0,0 +1,55 @@ +import fs from "fs"; +import path from "path"; +import { expect } from "chai"; +import { shell } from "../../src/utils/shell.js"; +import { getLocalBranchExists } from "../../src/utils/git.js"; +import { isValidRelease } from "../../src/commands/githubActions/bumpUpstream/github/isValidRelease.js"; +import { + executable, + temporaryDirectory, + useExecutables +} from "../helpers/fixtures.js"; + +describe("safe commands and line buffering", () => { + it("passes metacharacters literally instead of executing them", async () => { + const value = '$(touch SHOULD_NOT_EXIST);echo unsafe "quoted"'; + const result = await shell([ + "node", + "-e", + "process.stdout.write(process.argv[1])", + value + ]); + expect(result).to.equal(value); + expect(isValidRelease("v1.2.3$(touch${IFS}marker)")).to.equal(false); + }); + + it("never evaluates a branch name while checking whether it exists", async () => { + const dir = temporaryDirectory(); + const marker = path.join(dir, "marker"); + executable(dir, "git", "process.exit(1);"); + const restore = useExecutables(dir); + try { + expect( + await getLocalBranchExists(`demo$(touch\u0024{IFS}${marker})`) + ).to.equal(false); + expect(fs.existsSync(marker)).to.equal(false); + } finally { + restore(); + fs.rmSync(dir, { recursive: true, force: true }); + } + }); + + it("assembles partial UTF-8 lines independently on stdout and stderr", async () => { + const lines: string[] = []; + await shell( + [ + "node", + "-e", + 'process.stdout.write("hel"); process.stderr.write("warn\\n"); setTimeout(() => { process.stdout.write("lo\\nlast"); }, 30);' + ], + { onData: line => lines.push(line) } + ); + expect(lines).to.include("hello").and.include("warn").and.include("last"); + expect(lines).not.to.include("hel"); + }); +}); diff --git a/test/utils/progress.test.ts b/test/utils/progress.test.ts new file mode 100644 index 00000000..2e2030e8 --- /dev/null +++ b/test/utils/progress.test.ts @@ -0,0 +1,104 @@ +import { expect } from "chai"; +import { mock } from "node:test"; +import Listr from "listr"; +import { + renderProgress, + taskLog, + VerboseRenderer, + type ProgressTask +} from "../../src/utils/progress.js"; +import { shell } from "../../src/utils/shell.js"; + +function pending(title: string, output: string): ProgressTask { + return { + title, + output, + subtasks: [], + isEnabled: () => true, + isPending: () => true, + isCompleted: () => false, + isSkipped: () => false, + hasFailed: () => false + }; +} + +describe("build progress preview", () => { + afterEach(() => mock.restoreAll()); + + it("reports each log line once, as its own output update", () => { + const task: { output?: string } = {}; + const write = taskLog(task); + write("layer 1"); + expect(task.output).to.equal("layer 1"); + write("\u001b[32mlayer 2\u001b[0m"); + expect(task.output).to.equal("layer 2"); + }); + + it("shows the last few lines of a pending task from the renderer history", () => { + const task = pending("Build mainnet · linux/arm64", "layer 5"); + const history = new WeakMap([ + [task, ["layer 2", "layer 3", "layer 4", "layer 5"]] + ]); + const lines = renderProgress([task], "⠋", 0, history); + expect(lines.join("\n")).to.include("layer 2").and.include("layer 5"); + expect(lines[0]).to.include("mainnet").and.include("arm64"); + }); + + it("does not repeat the error under a failed task", () => { + const failed = { + ...pending("Build docker image", "Command failed (exit 1): docker build"), + isPending: () => false, + hasFailed: () => true + }; + const lines = renderProgress([failed], "⠋", 0, new WeakMap()); + expect(lines).to.deep.equal(["✖ Build docker image"]); + }); + + it("keeps the active upload/pinning stage visible without future task clutter", () => { + const task = pending( + "Upload mainnet", + "Upload sent · waiting for pinning confirmation..." + ); + const future = { ...pending("Future stage", ""), isPending: () => false }; + const lines = renderProgress([task, future]); + expect(lines.join("\n")).to.include("waiting for pinning confirmation"); + expect(lines.join("\n")).not.to.include("Future stage"); + }); + + it("logs every streamed line once in verbose mode and leaves the error to the CLI", async () => { + const logged: string[] = []; + mock.method(console, "log", (line: string) => logged.push(line)); + const error = await new Listr( + [ + { + title: "Build docker image", + task: (_, task) => + shell( + [ + "sh", + "-c", + "for i in 1 2 3 4 5 6; do echo step-$i; done; exit 3" + ], + { onData: taskLog(task) } + ) + } + ], + { renderer: VerboseRenderer } + ) + .run() + .catch(error => error); + mock.restoreAll(); + expect(error.summary).to.equal( + "Command failed (exit 3): sh -c for i in 1 2 3 4 5 6; do echo step-$i; done; exit 3" + ); + for (const step of [1, 2, 3, 4, 5, 6]) + expect( + logged.filter(line => line.includes(`step-${step}`)), + `step-${step}` + ).to.have.length(1); + expect(logged.some(line => line.includes("Command failed"))).to.equal( + false + ); + expect(logged.some(line => line.includes("[failed]"))).to.equal(true); + }); +}); diff --git a/test/utils/shell.test.ts b/test/utils/shell.test.ts index 04f5831b..86b3a56a 100644 --- a/test/utils/shell.test.ts +++ b/test/utils/shell.test.ts @@ -35,14 +35,13 @@ echo "hello" if (!error) throw Error("Command did not throw"); expect(error.message).to.equal( - `Command failed: cat does-not-exist -cat: does-not-exist: No such file or directory - -stdout: -stderr: cat: does-not-exist: No such file or directory -`, + `Command failed (exit 1): cat does-not-exist +cat: does-not-exist: No such file or directory`, "wrong error.message" ); + expect(error.summary).to.equal( + "Command failed (exit 1): cat does-not-exist" + ); expect({ cmd: error.cmd, @@ -57,6 +56,21 @@ stderr: cat: does-not-exist: No such file or directory }); }); + it("keeps only the last lines of long output in the message", async () => { + const error = await shell([ + "sh", + "-c", + "for i in $(seq 1 30); do echo line-$i >&2; done; exit 2" + ]).catch(e => e); + const lines = error.message.split("\n"); + expect(lines[0]).to.match(/^Command failed \(exit 2\): sh -c /); + expect(lines[1]).to.equal("... (10 earlier lines omitted)"); + expect(lines.slice(2)).to.deep.equal( + Array.from({ length: 20 }, (_, i) => `line-${i + 11}`) + ); + expect(error.stderr.split("\n").filter(Boolean)).to.have.length(30); + }); + after(() => { fs.unlinkSync(scriptPath); }); diff --git a/test/utils/timeout.test.ts b/test/utils/timeout.test.ts new file mode 100644 index 00000000..d8a215d1 --- /dev/null +++ b/test/utils/timeout.test.ts @@ -0,0 +1,26 @@ +import { expect } from "chai"; +import { parseTimeout } from "../../src/utils/timeout.js"; + +describe("parseTimeout", () => { + it("parses human-readable durations", () => { + expect(parseTimeout("20min")).to.equal(20 * 60 * 1000); + expect(parseTimeout("1h")).to.equal(60 * 60 * 1000); + }); + + it("treats a bare integer string as seconds, as documented by `--timeout 5000`", () => { + expect(parseTimeout("5000")).to.equal(5000 * 1000); + }); + + it("passes numeric milliseconds through, with 0 meaning no timeout", () => { + expect(parseTimeout(5000)).to.equal(5000); + expect(parseTimeout(0)).to.equal(0); + }); + + it("defaults when unset and rejects nonsense", () => { + expect(parseTimeout(undefined)).to.equal(60 * 60 * 1000); + expect(parseTimeout("")).to.equal(60 * 60 * 1000); + expect(() => parseTimeout("0")).to.throw("Invalid timeout"); + expect(() => parseTimeout(-1)).to.throw("Invalid timeout"); + expect(() => parseTimeout("abc")).to.throw(); + }); +}); diff --git a/test/utils/versions/getNextPackageVersion.test.ts b/test/utils/versions/getNextPackageVersion.test.ts index 0d1993d1..718dd20f 100644 --- a/test/utils/versions/getNextPackageVersion.test.ts +++ b/test/utils/versions/getNextPackageVersion.test.ts @@ -1,16 +1,7 @@ import { expect } from "chai"; import semver from "semver"; -import { cleanTestDir, generateCompose, testDir } from "../../testUtils.js"; -import { - defaultComposeFileName, - defaultManifestFormat -} from "../../../src/params.js"; -import { - writeCompose, - readCompose, - writeManifest, - readManifest -} from "../../../src/files/index.js"; +import { cleanTestDir, testDir } from "../../testUtils.js"; +import { writeCompose, writeManifest } from "../../../src/files/index.js"; import { Manifest } from "@dappnode/types"; import { ManifestFormat } from "../../../src/files/manifest/types.js"; import { getNextPackageVersion } from "../../../src/tasks/publish/subtasks/getFetchApmVersionsTask.js"; @@ -31,7 +22,13 @@ describe("getNextPackageVersion", function () { it("Should get the next version from APM and update manifest and compose files", async () => { // Write initial manifest and compose files writeManifest(manifest, ManifestFormat.json, { dir: testDir }); - writeCompose({ version: "3.8", services: { [dnpName]: { image: `${dnpName}:${manifest.version}` } } }, { dir: testDir }); + writeCompose( + { + version: "3.8", + services: { [dnpName]: { image: `${dnpName}:${manifest.version}` } } + }, + { dir: testDir } + ); // Fetch the next version from APM const nextVersion = await getNextPackageVersion({ @@ -41,6 +38,6 @@ describe("getNextPackageVersion", function () { }); // Ensure the next version is valid - expect(semver.valid(nextVersion)).to.be.ok; + expect(semver.valid(nextVersion)).to.not.equal(null); }); -}); \ No newline at end of file +}); diff --git a/test/utils/versions/updateVariantFiles.test.ts b/test/utils/versions/updateVariantFiles.test.ts index 9e4e9edf..2194f5f7 100644 --- a/test/utils/versions/updateVariantFiles.test.ts +++ b/test/utils/versions/updateVariantFiles.test.ts @@ -2,61 +2,65 @@ import { expect } from "chai"; import { cleanTestDir, testDir } from "../../testUtils.js"; import { defaultComposeFileName } from "../../../src/params.js"; import { - writeManifest, - readCompose, - writeCompose, - readManifest + writeManifest, + readCompose, + writeCompose, + readManifest } from "../../../src/files/index.js"; import { Compose, Manifest } from "@dappnode/types"; import { ManifestFormat } from "../../../src/files/manifest/types.js"; -import { updateVariantFiles, } from "../../../src/tasks/publish/subtasks/getUpdateFilesTask.js"; - +import { updateVariantFiles } from "../../../src/tasks/publish/subtasks/getUpdateFilesTask.js"; describe("Update Variant Files and Entries", function () { - this.timeout(60 * 1000); - - const dnpName = "admin.dnp.dappnode.eth"; - - const manifest: Manifest = { - name: dnpName, - version: "0.1.0", - type: "dncore" - }; - - const compose: Compose = { - version: "3.8", - services: { [dnpName]: { image: "override-me" } } - }; - - const nextVersion = "0.1.1"; - - before("Clean testDir", () => cleanTestDir()); - after("Clean testDir", () => cleanTestDir()); - - it("Should update manifest and compose files correctly for a single variant package", async () => { - // Write initial manifest and compose files - writeManifest(manifest, ManifestFormat.json, { dir: testDir }); - writeCompose(compose, { dir: testDir }); - - // Update variant files - updateVariantFiles({ - rootDir: testDir, - composeFileName: defaultComposeFileName, - variant: null, - variantsDirPath: testDir, - dnpName, - nextVersion, - }); - - // Check that the manifest was updated correctly - const { manifest: newManifest } = readManifest([{ dir: testDir }]); - expect(newManifest.version).to.equal(nextVersion, "Manifest version should be updated to the next version"); - - // Check that the compose was updated correctly - const updatedCompose = readCompose([{ dir: testDir, composeFileName: defaultComposeFileName }]); - expect(updatedCompose.services[dnpName].image).to.equal( - `${dnpName}:${nextVersion}`, - "Compose image should be updated to the next version" - ); + this.timeout(60 * 1000); + + const dnpName = "admin.dnp.dappnode.eth"; + + const manifest: Manifest = { + name: dnpName, + version: "0.1.0", + type: "dncore" + }; + + const compose: Compose = { + version: "3.8", + services: { [dnpName]: { image: "override-me" } } + }; + + const nextVersion = "0.1.1"; + + before("Clean testDir", () => cleanTestDir()); + after("Clean testDir", () => cleanTestDir()); + + it("Should update manifest and compose files correctly for a single variant package", async () => { + // Write initial manifest and compose files + writeManifest(manifest, ManifestFormat.json, { dir: testDir }); + writeCompose(compose, { dir: testDir }); + + // Update variant files + updateVariantFiles({ + rootDir: testDir, + composeFileName: defaultComposeFileName, + variant: null, + variantsDirPath: testDir, + dnpName, + nextVersion }); + + // Check that the manifest was updated correctly + const { manifest: newManifest } = readManifest([{ dir: testDir }]); + expect(newManifest.version).to.equal( + nextVersion, + "Manifest version should be updated to the next version" + ); + + // Check that the compose was updated correctly + const updatedCompose = readCompose([ + { dir: testDir, composeFileName: defaultComposeFileName } + ]); + expect(updatedCompose.services[dnpName].image).to.equal( + "override-me", + "External source image must remain unchanged" + ); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 3af61bd9..bc35c394 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,15 @@ { "compilerOptions": { - "target": "es2019", - "lib": ["ES2020", "dom"], + "target": "es2022", + "lib": ["ES2022", "dom"], "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "esModuleInterop": true, "resolveJsonModule": true, "strictNullChecks": true, "allowJs": true, "strict": true, + "isolatedModules": true, "types": ["mocha", "node"], "outDir": "dist", "sourceMap": true, @@ -16,11 +17,6 @@ "useUnknownInCatchVariables": false, "skipLibCheck": true }, - "ts-node": { - "esm": true, - "experimentalSpecifierResolution": "node", - "experimentalResolver": true - }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "**/*.test.ts"] } diff --git a/yarn.lock b/yarn.lock index f8e6fe30..8e1d3a54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,859 +2,815 @@ # yarn lockfile v1 -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz#6c2d657d4b2dfb37f8ea811dcb3e60843d4ac24a" + integrity sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ== -"@adraffy/ens-normalize@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.0.tgz#223572538f6bea336750039bb43a4016dcc8182d" - integrity sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ== - -"@babel/code-frame@^7.0.0": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@balena/dockerignore@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz" - integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== - -"@chainsafe/is-ip@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.1.tgz#62cb285669d91f88fd9fa285048dde3882f0993b" - integrity sha512-nqSJ8u2a1Rv9FYbyI8qpDhTYujaKEyLknNrTejLYoSWmdeg+2WB7R6BZqPZYfrJzDxVi3rl6ZQuoaEvpKRZWgQ== - -"@chainsafe/netmask@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/netmask/-/netmask-2.0.0.tgz#0d4a75f47919f65011da4327a3845c9661f1038a" - integrity sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg== +"@cacheable/memory@^2.2.0": + version "2.2.0" + resolved "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz#72aeb8b051f6d597d10ac8595b94ad8302bd2239" + integrity sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ== dependencies: - "@chainsafe/is-ip" "^2.0.1" + "@cacheable/utils" "^2.5.0" + "@keyv/bigmap" "^1.3.1" + hookified "^1.15.1" + keyv "^5.6.0" -"@cspotcode/source-map-support@^0.8.0": - 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== +"@cacheable/utils@^2.5.0": + version "2.5.0" + resolved "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz#534c91113aa48fe43baedb169550b6ee070ef303" + integrity sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA== dependencies: - "@jridgewell/trace-mapping" "0.3.9" + hashery "^1.5.1" + keyv "^5.6.0" "@dappnode/schemas@^0.1.26": version "0.1.26" - resolved "https://registry.yarnpkg.com/@dappnode/schemas/-/schemas-0.1.26.tgz#45ac97dd7e59fe7914b24d723a3489107733b65d" + resolved "https://registry.npmjs.org/@dappnode/schemas/-/schemas-0.1.26.tgz#45ac97dd7e59fe7914b24d723a3489107733b65d" integrity sha512-i9jkn8vDYumaTbo0mGLqm3ONyLiCYoHbRTzS47WYdWQONP/Bxou42XPqM6KFxAvyMRCv6oUCmRu0sNs4Gzq3qw== dependencies: "@dappnode/types" "^0.1.40" ajv "^8.17.1" semver "^7.5.0" -"@dappnode/toolkit@^0.1.21": - version "0.1.21" - resolved "https://registry.yarnpkg.com/@dappnode/toolkit/-/toolkit-0.1.21.tgz#f5bc8158dcb86415dae0bec0f137690361a9db80" - integrity sha512-hbggqq9xPb6kzLTFduHkJFHgQEcBFoBwpmPsPCJZDf21hlRh7+sbcxRoU/pEW48cxXLQ/O6uMFH1v44j+cREVA== - dependencies: - "@dappnode/types" "^0.1.34" - "@ipld/car" "^5.1.1" - esm "^3.2.25" - ethers "^6.9.0" - graphql "^16.6.0" - graphql-request "^6.0.0" - ipfs-unixfs-exporter "^13.1.5" - is-ipfs "^8.0.1" - kubo-rpc-client "^3.0.1" - multiformats "^11.0.2" - semver "^7.5.0" - yaml "^2.2.2" - -"@dappnode/types@^0.1.34": - version "0.1.34" - resolved "https://registry.yarnpkg.com/@dappnode/types/-/types-0.1.34.tgz#f84713687860b569e405884132a953e4ee4b8ade" - integrity sha512-07DEQVP6umDUDhDcX8m7EZMZtUUeyOeigupTWo8/oNsHuw7/V+UMCnUjYr1UsoNug2B3nRJ4V+iYQl0R/fhBEQ== - -"@dappnode/types@^0.1.40": - version "0.1.40" - resolved "https://registry.yarnpkg.com/@dappnode/types/-/types-0.1.40.tgz#d64947867d91a4b7b6b4fed4a3ae815e392cbf99" - integrity sha512-gq0PswPB4y09SLpK+MYJti841/jcFTjqoVT+rcrwvOsSEFk6KUyCLxLahFKUJ9Z5w5iBiSLeJ1kmNQk/PRvT9Q== - -"@dappnode/types@^0.1.41": +"@dappnode/types@^0.1.40", "@dappnode/types@^0.1.41": version "0.1.41" - resolved "https://registry.yarnpkg.com/@dappnode/types/-/types-0.1.41.tgz#43920962ed37574914c7e22273104028fdd0995f" + resolved "https://registry.npmjs.org/@dappnode/types/-/types-0.1.41.tgz#43920962ed37574914c7e22273104028fdd0995f" integrity sha512-lhPoVo50ZL+VimLl2laTehJIIADNzzGJgb+cgJ5a1mYYxLm3FjLAOLK+V2UII2ZfcCW7WJqOSw6gUXMRnJFRng== -"@graphql-typed-document-node/core@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" - integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== +"@esbuild/aix-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz#bf6e10303bcf2e7c686975fa52f937ec2728d8bc" + integrity sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ== + +"@esbuild/android-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz#0c6246bc8d2c4d172aac2db3fb1190d72bd65504" + integrity sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A== + +"@esbuild/android-arm@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz#2d84ece6a4e2684d92be26ee13d42757d831c381" + integrity sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg== + +"@esbuild/android-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz#fc38d4d6358d8dc1cf53f09f7589fe436eb64801" + integrity sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q== + +"@esbuild/darwin-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz#f83afeeac1d7dac01c7a2fd012b3e451a0591fcc" + integrity sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw== + +"@esbuild/darwin-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz#510147c055a795588dbbe14fd6b1b8ad0a2f30de" + integrity sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw== + +"@esbuild/freebsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz#093b9200ecf0b115ba4e5e248a7485c9c5f8bd5e" + integrity sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw== + +"@esbuild/freebsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz#0be22b6df925d213e841ea87123af5df80b0faf7" + integrity sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg== + +"@esbuild/linux-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz#1bdbc651cda9ba9995c53ed9c71ceaa65094762d" + integrity sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug== + +"@esbuild/linux-arm@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz#beb12ad72b84f72d28488cc1b8ee9f7eb141d753" + integrity sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w== + +"@esbuild/linux-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz#b81f9d55529b45c206a46a138214b1aa6879696b" + integrity sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ== + +"@esbuild/linux-loong64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz#598667241a04c99b76ed6ef940ac50038c419f98" + integrity sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ== + +"@esbuild/linux-mips64el@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz#1c51eb9cea903f53d97b5af3b1841db70f5596ca" + integrity sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA== + +"@esbuild/linux-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz#63dd61f17ceb31a81227f413feac8a71bc2c51f2" + integrity sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ== + +"@esbuild/linux-riscv64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz#3763b08fde5cf25ab1facb8e7752edfe45fbfc27" + integrity sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA== + +"@esbuild/linux-s390x@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz#1a137ff293a82906eb3176385bd7e8e0e5cfb7cb" + integrity sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg== + +"@esbuild/linux-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz#268b36211c146ca54f8fe12c578a8d6ef8979485" + integrity sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ== + +"@esbuild/netbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz#22571ad951d62bb6accc82d8d1fad5c8c1ac0ba1" + integrity sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw== + +"@esbuild/netbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz#42fcc57297eb0a0ca3f5fc475291f4c1a3f7c0de" + integrity sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw== + +"@esbuild/openbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz#9eb32af104ac3dacf4edca01f596664aab0c73ef" + integrity sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ== + +"@esbuild/openbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz#febed2402d6088225e91f20fb4ce2522ad0a4efd" + integrity sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw== + +"@esbuild/openharmony-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz#85641c3d466428bfbccea5f21c26836663fef5ce" + integrity sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q== + +"@esbuild/sunos-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz#a736f9d8962481045fc4c3e54f5479f22c870fb4" + integrity sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g== + +"@esbuild/win32-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz#ee5ab40fad186201b652a33f8a5eb149e9e42532" + integrity sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ== + +"@esbuild/win32-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz#c40d28a6d99a127da6711f2afd74b11cb63b06a7" + integrity sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA== + +"@esbuild/win32-x64@0.28.2": + version "0.28.2" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz#b21affb804cc167c133d95f45b3a1dc1323b9a87" + integrity sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g== + +"@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": + version "4.10.1" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz#8911bd72b2c3640a543609e0400b8c4d2e7e7cb6" + integrity sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/regexpp@^4.12.2": + version "4.12.2" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + +"@eslint/config-array@^0.23.5": + version "0.23.5" + resolved "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz#56e86d243049195d8acc0c06a1b3dfdc3fa3de95" + integrity sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA== + dependencies: + "@eslint/object-schema" "^3.0.5" + debug "^4.3.1" + minimatch "^10.2.4" -"@ipld/car@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@ipld/car/-/car-5.1.1.tgz#14a26dc97c4783ade491ac811f61885259b9d75e" - integrity sha512-HoFTUqUJL9cPGhC9qRmHCvamfIsj1JllQSQ/Xu9/KN/VNJp8To9Ms4qiZPEMOwcrNFclfYqrahjGYbf4KL/d9A== +"@eslint/config-helpers@^0.7.0": + version "0.7.0" + resolved "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz#09ee4aa07b73f059ec2d4c74bf4b2ff02b322377" + integrity sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw== dependencies: - "@ipld/dag-cbor" "^9.0.0" - cborg "^1.9.0" - multiformats "^11.0.0" - varint "^6.0.0" + "@eslint/core" "^1.2.1" -"@ipld/dag-cbor@^9.0.0": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@ipld/dag-cbor/-/dag-cbor-9.0.1.tgz#fc7c76af284b74b3a67b003a768d2c4758841272" - integrity sha512-tImDka4akO7cuD24+nRLOU1kYXoai3VZ1cMeWCFUzwhKrRXyOLfVd9RZGI6aTsE/PYvHmkFobKvTeK9NPVtajA== +"@eslint/core@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz#c1da7cd1b82fa8787f98b5629fb811848a1b63ce" + integrity sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ== dependencies: - cborg "^1.10.0" - multiformats "^11.0.0" + "@types/json-schema" "^7.0.15" -"@ipld/dag-json@^10.0.0": - version "10.1.0" - resolved "https://registry.yarnpkg.com/@ipld/dag-json/-/dag-json-10.1.0.tgz#9cad1628d9ef6df0d732d2d468adb53987d1111d" - integrity sha512-2rSvzDyGxx1NC24IsqKFTSXzAfUBlniZQRT15PEN+i177KEBsCXPfxuN/DweGIfmj3YceNyR8XOJT47pRZu7Cg== - dependencies: - cborg "^1.10.0" - multiformats "^11.0.0" +"@eslint/js@^10.0.1": + version "10.0.1" + resolved "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz#1e8a876f50117af8ab67e47d5ad94d38d6622583" + integrity sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA== -"@ipld/dag-pb@^4.0.0": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@ipld/dag-pb/-/dag-pb-4.0.3.tgz#2fedd3804ad46ea6206be9302bfed5d3a0af26b3" - integrity sha512-bOe+Z2ZJs9pmP/aIUBYMTdXq0i5z1x71qXeOIIhZvnKFLuzTIbbW0u5b7OfTGzUEbSv1dkUZBIXa7G/+OA8dnA== +"@eslint/object-schema@^3.0.5": + version "3.0.5" + resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz#88e9bf4d11d2b19c082e78ebe7ce88724a5eb091" + integrity sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw== + +"@eslint/plugin-kit@^0.7.3": + version "0.7.3" + resolved "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz#cc7268cc36405b331ef92db1bc37971f21d66fe1" + integrity sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q== dependencies: - multiformats "^11.0.0" + "@eslint/core" "^1.2.1" + levn "^0.4.1" -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@libp2p/crypto@^1.0.11": - version "1.0.17" - resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-1.0.17.tgz#e64043328c0c866bf7f4cc8560b4f483e9c745dc" - integrity sha512-Oeg0Eb/EvAho0gVkOgemXEgrVxWaT3x/DpFgkBdZ9qGxwq75w/E/oPc7souqBz+l1swfz37GWnwV7bIb4Xv5Ag== - dependencies: - "@libp2p/interface-keys" "^1.0.2" - "@libp2p/interfaces" "^3.2.0" - "@noble/ed25519" "^1.6.0" - "@noble/secp256k1" "^1.5.4" - multiformats "^11.0.0" - node-forge "^1.1.0" - protons-runtime "^5.0.0" - uint8arraylist "^2.4.3" - uint8arrays "^4.0.2" - -"@libp2p/interface-connection@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@libp2p/interface-connection/-/interface-connection-4.0.0.tgz#fcc830ca891820fac89a4c6bd4fcc2df4874f49b" - integrity sha512-6xx/NmEc84HX7QmsjSC3hHredQYjHv4Dkf4G27adAPf+qN+vnPxmQ7gaTnk243a0++DOFTbZ2gKX/15G2B6SRg== +"@humanfs/core@^0.19.2": + version "0.19.2" + resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz#a8272ca03b2acf492670222b2320b6c421bfde60" + integrity sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA== dependencies: - "@libp2p/interface-peer-id" "^2.0.0" - "@libp2p/interfaces" "^3.0.0" - "@multiformats/multiaddr" "^12.0.0" - it-stream-types "^1.0.4" - uint8arraylist "^2.1.2" + "@humanfs/types" "^0.15.0" -"@libp2p/interface-keychain@^2.0.0": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@libp2p/interface-keychain/-/interface-keychain-2.0.5.tgz#6ce104f38cf07ad72c9dfbe471a689f4ea4b4687" - integrity sha512-mb7QNgn9fIvC7CaJCi06GJ+a6DN6RVT9TmEi0NmedZGATeCArPeWWG7r7IfxNVXb9cVOOE1RzV1swK0ZxEJF9Q== +"@humanfs/node@^0.16.8": + version "0.16.8" + resolved "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz#8f800cccc13f4f8cd3116e2d9c0a94939da3e3ed" + integrity sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ== dependencies: - "@libp2p/interface-peer-id" "^2.0.0" - multiformats "^11.0.0" + "@humanfs/core" "^0.19.2" + "@humanfs/types" "^0.15.0" + "@humanwhocodes/retry" "^0.4.0" -"@libp2p/interface-keys@^1.0.2": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@libp2p/interface-keys/-/interface-keys-1.0.8.tgz#2c6b55136113ae7cf78133d3c459cdf0455b29ae" - integrity sha512-CJ1SlrwuoHMquhEEWS77E+4vv7hwB7XORkqzGQrPQmA9MRdIEZRS64bA4JqCLUDa4ltH0l+U1vp0oZHLT67NEA== +"@humanfs/types@^0.15.0": + version "0.15.0" + resolved "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz#f2a09f62012390b2bff3fc6fb248ddec8c09a090" + integrity sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q== -"@libp2p/interface-peer-id@^2.0.0", "@libp2p/interface-peer-id@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@libp2p/interface-peer-id/-/interface-peer-id-2.0.2.tgz#6302e70b6fc17c451bc3daa11447d059357bcc32" - integrity sha512-9pZp9zhTDoVwzRmp0Wtxw0Yfa//Yc0GqBCJi3EznBDE6HGIAVvppR91wSh2knt/0eYg0AQj7Y35VSesUTzMCUg== - dependencies: - multiformats "^11.0.0" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@libp2p/interface-peer-info@^1.0.2": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@libp2p/interface-peer-info/-/interface-peer-info-1.0.10.tgz#566026de95a0817b9e853c982b313541b7960c0b" - integrity sha512-HQlo8NwQjMyamCHJrnILEZz+YwEOXCB2sIIw3slIrhVUYeYlTaia1R6d9umaAeLHa255Zmdm4qGH8rJLRqhCcg== - dependencies: - "@libp2p/interface-peer-id" "^2.0.0" - "@multiformats/multiaddr" "^12.0.0" +"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2": + version "0.4.3" + resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" + integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== -"@libp2p/interface-pubsub@^3.0.0": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@libp2p/interface-pubsub/-/interface-pubsub-3.0.7.tgz#cc1c7c47c883daddd2b84d83d719b3826943be3b" - integrity sha512-+c74EVUBTfw2sx1GE/z/IjsYO6dhur+ukF0knAppeZsRQ1Kgg6K5R3eECtT28fC6dBWLjFpAvW/7QGfiDAL4RA== - dependencies: - "@libp2p/interface-connection" "^4.0.0" - "@libp2p/interface-peer-id" "^2.0.0" - "@libp2p/interfaces" "^3.0.0" - it-pushable "^3.0.0" - uint8arraylist "^2.1.2" - -"@libp2p/interfaces@^3.0.0", "@libp2p/interfaces@^3.2.0", "@libp2p/interfaces@^3.3.1": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@libp2p/interfaces/-/interfaces-3.3.2.tgz#5d8079be845b0960939b5b18880e785a4714465a" - integrity sha512-p/M7plbrxLzuQchvNwww1Was7ZeGE2NaOFulMaZBYIihU8z3fhaV+a033OqnC/0NTX/yhfdNOG7znhYq3XoR/g== - -"@libp2p/logger@^2.0.0": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-2.0.7.tgz#9a3996242b4a9edb8a9d825c8accaf62f617c5c6" - integrity sha512-Zp9C9lMNGfVFTMVc7NvxuxMvIE6gyxDapQc/TqZH02IuIDl1JpZyCgNILr0APd8wcUxwvwRXYNf3kQ0Lmz7tuQ== - dependencies: - "@libp2p/interface-peer-id" "^2.0.0" - debug "^4.3.3" - interface-datastore "^8.0.0" - multiformats "^11.0.0" - -"@libp2p/logger@^2.0.5": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-2.1.1.tgz#e12e6c320ea64252af954bcec996895098d1cd36" - integrity sha512-2UbzDPctg3cPupF6jrv6abQnAUTrbLybNOj0rmmrdGm1cN2HJ1o/hBu0sXuq4KF9P1h/eVRn1HIRbVIEKnEJrA== - dependencies: - "@libp2p/interface-peer-id" "^2.0.2" - "@multiformats/multiaddr" "^12.1.3" - debug "^4.3.4" - interface-datastore "^8.2.0" - multiformats "^11.0.2" +"@inquirer/ansi@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz#674a4c4d81ad460695cb2a1fc69d78cd187f337e" + integrity sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ== + +"@inquirer/checkbox@^4.3.2": + version "4.3.2" + resolved "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz#e1483e6519d6ffef97281a54d2a5baa0d81b3f3b" + integrity sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/confirm@^5.1.21": + version "5.1.21" + resolved "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz#610c4acd7797d94890a6e2dde2c98eb1e891dd12" + integrity sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/core@^10.3.2": + version "10.3.2" + resolved "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz#535979ff3ff4fe1e7cc4f83e2320504c743b7e20" + integrity sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.3" + +"@inquirer/editor@^4.2.23": + version "4.2.23" + resolved "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz#fe046a3bfdae931262de98c1052437d794322e0b" + integrity sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/external-editor" "^1.0.3" + "@inquirer/type" "^3.0.10" + +"@inquirer/expand@^4.0.23": + version "4.0.23" + resolved "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz#a38b5f32226d75717c370bdfed792313b92bdc05" + integrity sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/external-editor@^1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz#c23988291ee676290fdab3fd306e64010a6d13b8" + integrity sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA== + dependencies: + chardet "^2.1.1" + iconv-lite "^0.7.0" + +"@inquirer/figures@^1.0.15": + version "1.0.15" + resolved "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz#dbb49ed80df11df74268023b496ac5d9acd22b3a" + integrity sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== + +"@inquirer/input@^4.3.1": + version "4.3.1" + resolved "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz#778683b4c4c4d95d05d4b05c4a854964b73565b4" + integrity sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/number@^3.0.23": + version "3.0.23" + resolved "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz#3fdec2540d642093fd7526818fd8d4bdc7335094" + integrity sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/password@^4.0.23": + version "4.0.23" + resolved "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz#b9f5187c8c92fd7aa9eceb9d8f2ead0d7e7b000d" + integrity sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + +"@inquirer/prompts@^7.10.1": + version "7.10.1" + resolved "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz#e1436c0484cf04c22548c74e2cd239e989d5f847" + integrity sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg== + dependencies: + "@inquirer/checkbox" "^4.3.2" + "@inquirer/confirm" "^5.1.21" + "@inquirer/editor" "^4.2.23" + "@inquirer/expand" "^4.0.23" + "@inquirer/input" "^4.3.1" + "@inquirer/number" "^3.0.23" + "@inquirer/password" "^4.0.23" + "@inquirer/rawlist" "^4.1.11" + "@inquirer/search" "^3.2.2" + "@inquirer/select" "^4.4.2" + +"@inquirer/rawlist@^4.1.11": + version "4.1.11" + resolved "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz#313c8c3ffccb7d41e990c606465726b4a898a033" + integrity sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/search@^3.2.2": + version "3.2.2" + resolved "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz#4cc6fd574dcd434e4399badc37c742c3fd534ac8" + integrity sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA== + dependencies: + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/select@^4.4.2": + version "4.4.2" + resolved "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz#2ac8fca960913f18f1d1b35323ed8fcd27d89323" + integrity sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/figures" "^1.0.15" + "@inquirer/type" "^3.0.10" + yoctocolors-cjs "^2.1.3" + +"@inquirer/type@^3.0.10": + version "3.0.10" + resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz#11ed564ec78432a200ea2601a212d24af8150d50" + integrity sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== + +"@isaacs/nonrecursive-glob-match@^1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@isaacs/nonrecursive-glob-match/-/nonrecursive-glob-match-1.0.3.tgz#7f6724fd8a6ca315d6bb7f63f0e4d079060da246" + integrity sha512-SI7kyKHq4XXDRozw+r9GlRZkia1ZkFrpLW98r2IC2Bpr8YkFGE3fvjzmxCG0x78A++69HmDNrDvSMYBZmHGpKA== -"@libp2p/peer-id@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-2.0.3.tgz#7299d74eae7b2526123d941bdb2d08462704c79a" - integrity sha512-eZX+5ByUAzh8DrfjCan0spZGpvF7SxEBz4tOPoBMBCuKJJLr+8EokBO/5E3ceIw04f5+lAcD3CO3bccuKomp3Q== - dependencies: - "@libp2p/interface-peer-id" "^2.0.0" - "@libp2p/interfaces" "^3.2.0" - multiformats "^11.0.0" - uint8arrays "^4.0.2" - -"@multiformats/mafmt@^11.0.3": - version "11.1.2" - resolved "https://registry.yarnpkg.com/@multiformats/mafmt/-/mafmt-11.1.2.tgz#c03ef4022c795b7f230b136f2f974fc263eac4f1" - integrity sha512-3n1o5eLU7WzTAPLuz3AodV7Iql6NWf7Ws8fqVaGT7o5nDDabUPYGBm2cZuh3OrqmwyCY61LrNUIsjzivU6UdpQ== - dependencies: - "@multiformats/multiaddr" "^12.0.0" - -"@multiformats/multiaddr-to-uri@^9.0.1": - version "9.0.7" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-to-uri/-/multiaddr-to-uri-9.0.7.tgz#44881352b1d9d98b53451982cd433f0f45ad7e24" - integrity sha512-i3ldtPMN6XJt+MCi34hOl0wGuGEHfWWMw6lmNag5BpckPwPTf9XGOOFMmh7ed/uO3Vjah/g173iOe61HTQVoBA== - dependencies: - "@multiformats/multiaddr" "^12.0.0" - -"@multiformats/multiaddr@^11.0.0", "@multiformats/multiaddr@^11.1.5": - version "11.6.1" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-11.6.1.tgz#ec46984a298e715e27a398434c087856db5f3185" - integrity sha512-doST0+aB7/3dGK9+U5y3mtF3jq85KGbke1QiH0KE1F5mGQ9y56mFebTeu2D9FNOm+OT6UHb8Ss8vbSnpGjeLNw== - dependencies: - "@chainsafe/is-ip" "^2.0.1" - dns-over-http-resolver "^2.1.0" - err-code "^3.0.1" - multiformats "^11.0.0" - uint8arrays "^4.0.2" - varint "^6.0.0" - -"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.3": - version "12.1.3" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.1.3.tgz#aff5aa61ec19c5320f0b756e88c3bbaac8d1c7af" - integrity sha512-rNcS3njkkSwuGF4x58L47jGH5kBXBfJPNsWnrt0gujhNYn6ReDt1je7vEU5/ddrVj0TStgxw+Hm+TkYDK0b60w== - dependencies: - "@chainsafe/is-ip" "^2.0.1" - "@chainsafe/netmask" "^2.0.0" - "@libp2p/interfaces" "^3.3.1" - dns-over-http-resolver "^2.1.0" - multiformats "^11.0.0" - uint8arrays "^4.0.2" - varint "^6.0.0" - -"@multiformats/murmur3@^2.0.0": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@multiformats/murmur3/-/murmur3-2.1.4.tgz#e93cce560c381f8326b2271facf2ea04f6fd8a66" - integrity sha512-qHHmZKD1Dy6PDi35pAowE1pQtnH7gwaJpUE/Ju+cOYVdWD4T8VVtKAumGCxwd31JKyNC0W1IzAaHQz1dnXXvBw== +"@keyv/bigmap@^1.3.1": + version "1.3.1" + resolved "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz#fc82fa83947e7ff68c6798d08907db842771ef2c" + integrity sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ== dependencies: - multiformats "^11.0.0" - murmurhash3js-revisited "^3.0.0" + hashery "^1.4.0" + hookified "^1.15.0" + +"@keyv/serialize@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz#0c01dd3a3483882af7cf3878d4e71d505c81fc4a" + integrity sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA== "@noble/curves@1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== dependencies: "@noble/hashes" "1.3.2" -"@noble/ed25519@^1.6.0": - version "1.7.3" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" - integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ== - -"@noble/hashes@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== - "@noble/hashes@1.3.2": version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/secp256k1@1.7.1", "@noble/secp256k1@^1.5.4": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - -"@octokit/auth-token@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-4.0.0.tgz#40d203ea827b9f17f42a29c6afb93b7745ef80c7" - integrity sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA== - -"@octokit/core@^5.0.2": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-5.2.0.tgz#ddbeaefc6b44a39834e1bb2e58a49a117672a7ea" - integrity sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg== - dependencies: - "@octokit/auth-token" "^4.0.0" - "@octokit/graphql" "^7.1.0" - "@octokit/request" "^8.3.1" - "@octokit/request-error" "^5.1.0" - "@octokit/types" "^13.0.0" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - -"@octokit/endpoint@^9.0.1": +"@octokit/auth-token@^6.0.0": + version "6.0.0" + resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz#b02e9c08a2d8937df09a2a981f226ad219174c53" + integrity sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w== + +"@octokit/core@^7.0.6": + version "7.0.8" + resolved "https://registry.npmjs.org/@octokit/core/-/core-7.0.8.tgz#bc8c05bc3a0200d1f453d4fe59c9053a7446c9f3" + integrity sha512-L7y8eYc+AwxGr2PWI4WFt1VG4TiJ66c26BD16mXpYIlXxG0SMigM1+m4aTSlYyBr5BlQsGAlz8uDCoZN4SEMcg== + dependencies: + "@octokit/auth-token" "^6.0.0" + "@octokit/graphql" "^9.0.5" + "@octokit/request" "^10.0.16" + "@octokit/request-error" "^7.1.2" + "@octokit/types" "^18.0.0" + before-after-hook "^4.0.0" + universal-user-agent "^7.0.0" + +"@octokit/endpoint@^11.0.5": + version "11.0.5" + resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.5.tgz#d7ec88843bfeeea692fee97b52e7c2cdc0393db4" + integrity sha512-iXa654H3yFafF/ieHkukfbgWo2rmXD2ceD0ZOtrPhw1bc3FDch1d9N/TNs0FQ1/cIbwb7kspUX8jzIs8nzb9DQ== + dependencies: + "@octokit/types" "^18.0.0" + universal-user-agent "^7.0.2" + +"@octokit/graphql@^9.0.5": version "9.0.5" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-9.0.5.tgz#e6c0ee684e307614c02fc6ac12274c50da465c44" - integrity sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw== + resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.5.tgz#da0bc3584d79f958e5373b5ed1e98425ca5efdc0" + integrity sha512-bt/hm03LeU6Vy7FwTrkkC9p3XGT/lBwClglMqxBSe5/q0E5CdJTXeAqEI0vlw89/LF/G6tryTIH8HirZ3prMVg== dependencies: - "@octokit/types" "^13.1.0" - universal-user-agent "^6.0.0" + "@octokit/request" "^10.0.16" + "@octokit/types" "^18.0.0" + universal-user-agent "^7.0.0" -"@octokit/graphql@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-7.1.0.tgz#9bc1c5de92f026648131f04101cab949eeffe4e0" - integrity sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ== - dependencies: - "@octokit/request" "^8.3.0" - "@octokit/types" "^13.0.0" - universal-user-agent "^6.0.0" +"@octokit/openapi-types@^27.0.0": + version "27.0.0" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz#374ea53781965fd02a9d36cacb97e152cefff12d" + integrity sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA== -"@octokit/openapi-types@^22.2.0": - version "22.2.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e" - integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg== +"@octokit/openapi-types@^29.0.1": + version "29.0.1" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz#05895cc8ae328058e7af75b608c4c97f0bc1bc00" + integrity sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg== -"@octokit/plugin-paginate-rest@11.3.1": - version "11.3.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz#fe92d04b49f134165d6fbb716e765c2f313ad364" - integrity sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g== +"@octokit/plugin-paginate-rest@^14.0.0": + version "14.0.0" + resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz#44dc9fff2dacb148d4c5c788b573ddc044503026" + integrity sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw== dependencies: - "@octokit/types" "^13.5.0" + "@octokit/types" "^16.0.0" -"@octokit/plugin-request-log@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz#98a3ca96e0b107380664708111864cb96551f958" - integrity sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA== +"@octokit/plugin-request-log@^6.0.0": + version "6.0.0" + resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz#de1c1e557df6c08adb631bf78264fa741e01b317" + integrity sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q== -"@octokit/plugin-rest-endpoint-methods@13.2.2": - version "13.2.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz#af8e5dd2cddfea576f92ffaf9cb84659f302a638" - integrity sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA== +"@octokit/plugin-rest-endpoint-methods@^17.0.0": + version "17.0.0" + resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz#8c54397d3a4060356a1c8a974191ebf945924105" + integrity sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw== dependencies: - "@octokit/types" "^13.5.0" + "@octokit/types" "^16.0.0" -"@octokit/request-error@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-5.1.0.tgz#ee4138538d08c81a60be3f320cd71063064a3b30" - integrity sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q== +"@octokit/request-error@^7.1.2": + version "7.1.2" + resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.2.tgz#0477f3ec1034869205f8bd80560f2bc55b659973" + integrity sha512-XZRuT3xZ84D3gYErI1DZvhJ33dCWVV6uzBtWkaBB4TvA/L6eOeTZodxLFVB44bBEEo3vEx7y00UfX1tBLrtLRg== dependencies: - "@octokit/types" "^13.1.0" - deprecation "^2.0.0" - once "^1.4.0" + "@octokit/types" "^18.0.0" -"@octokit/request@^8.3.0", "@octokit/request@^8.3.1": - version "8.4.0" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-8.4.0.tgz#7f4b7b1daa3d1f48c0977ad8fffa2c18adef8974" - integrity sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw== +"@octokit/request@^10.0.16": + version "10.0.16" + resolved "https://registry.npmjs.org/@octokit/request/-/request-10.0.16.tgz#b548f8f848ffe4ccf5082142fac096fe7b8222b2" + integrity sha512-A0zWGjHzISIb+9ccG8s0dq7LKO5zVpJLRICjgUb+sJxEWqn8RUHB1rD3AE51+PECvXHIxqZ1VVvs4fHTSD9nUQ== dependencies: - "@octokit/endpoint" "^9.0.1" - "@octokit/request-error" "^5.1.0" - "@octokit/types" "^13.1.0" - universal-user-agent "^6.0.0" + "@octokit/endpoint" "^11.0.5" + "@octokit/request-error" "^7.1.2" + "@octokit/types" "^18.0.0" + content-type "^3.0.0" + json-with-bigint "^3.5.12" + universal-user-agent "^7.0.2" -"@octokit/rest@^20.1.1": - version "20.1.1" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-20.1.1.tgz#ec775864f53fb42037a954b9a40d4f5275b3dc95" - integrity sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw== +"@octokit/rest@^22.0.1": + version "22.0.1" + resolved "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz#4d866c32b76b711d3f736f91992e2b534163b416" + integrity sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw== dependencies: - "@octokit/core" "^5.0.2" - "@octokit/plugin-paginate-rest" "11.3.1" - "@octokit/plugin-request-log" "^4.0.0" - "@octokit/plugin-rest-endpoint-methods" "13.2.2" + "@octokit/core" "^7.0.6" + "@octokit/plugin-paginate-rest" "^14.0.0" + "@octokit/plugin-request-log" "^6.0.0" + "@octokit/plugin-rest-endpoint-methods" "^17.0.0" -"@octokit/types@^13.0.0", "@octokit/types@^13.1.0", "@octokit/types@^13.5.0": - version "13.5.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.5.0.tgz#4796e56b7b267ebc7c921dcec262b3d5bfb18883" - integrity sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ== +"@octokit/types@^16.0.0": + version "16.0.0" + resolved "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz#fbd7fa590c2ef22af881b1d79758bfaa234dbb7c" + integrity sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg== dependencies: - "@octokit/openapi-types" "^22.2.0" + "@octokit/openapi-types" "^27.0.0" -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== +"@octokit/types@^18.0.0": + version "18.0.0" + resolved "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz#763eeebafb488d8ea8a8322eafb2d9b1885d2844" + integrity sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA== dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + "@octokit/openapi-types" "^29.0.1" "@samverschueren/stream-to-observable@^0.3.0": - version "0.3.0" - resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz" - integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + version "0.3.1" + resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz#a21117b19ee9be70c379ec1877537ef2e1c63301" + integrity sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ== dependencies: any-observable "^0.3.0" -"@sindresorhus/is@^5.2.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" - integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== - -"@szmarczak/http-timer@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" - integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== - dependencies: - defer-to-connect "^2.0.1" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== +"@sec-ant/readable-stream@^0.4.1": + version "0.4.1" + resolved "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" + integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== +"@sindresorhus/is@^7.0.1": + version "7.2.0" + resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz#7c594e1a64336d2008d99d814056d459421504d4" + integrity sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw== "@types/async-retry@^1.4.2": - version "1.4.2" - resolved "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.2.tgz" - integrity sha512-GUDuJURF0YiJZ+CBjNQA0+vbP/VHlJbB0sFqkzsV7EcOPRfurVonXpXKAt3w8qIjM1TEzpz6hc6POocPvHOS3w== + version "1.4.9" + resolved "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.9.tgz#47d118e835864d633b5208a78a6907b1b44e50bc" + integrity sha512-s1ciZQJzRh3708X/m3vPExr5KJlzlZJvXsKpbtE2luqNcbROr64qU+3KpJsYHqWMeaxI839OvXf9PrUSw1Xtyg== dependencies: "@types/retry" "*" -"@types/caseless@*": - version "0.12.2" - resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz" - integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== - "@types/chai@^4.3.4": - version "4.3.4" - resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== + version "4.3.20" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== "@types/cli-progress@^3.7.0": - version "3.7.0" - resolved "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.7.0.tgz" - integrity sha512-h/f9+pomRHSodXOPgBjlLEESWhv2Z34pP5djmruylvEZ7MzTd1pljOmdsBpVh3uCGjTVOzb2ux8ZaXYqyPFgpQ== + version "3.11.6" + resolved "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.6.tgz#94b334ebe4190f710e51c1bf9b4fedb681fa9e45" + integrity sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA== dependencies: "@types/node" "*" -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/docker-modem@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.2.tgz" - integrity sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ== - dependencies: - "@types/node" "*" - "@types/ssh2" "*" +"@types/esrecurse@^4.3.1": + version "4.3.1" + resolved "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz#6f636af962fbe6191b830bd676ba5986926bccec" + integrity sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw== -"@types/dockerode@^3.3.16": - version "3.3.16" - resolved "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.16.tgz" - integrity sha512-ZAX2VrkTjwjk1808T8m6vMr+CFXSLiDD+tkEkLThI+v83AfzlYQZEWfZKwFyk1PWopSXkdDunmIhrF7sxt+zWg== - dependencies: - "@types/docker-modem" "*" - "@types/node" "*" - -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/estree@^1.0.6", "@types/estree@^1.0.8": + version "1.0.10" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz#8a4a266065af8c2fcf5983153cd97c11b313d0c6" + integrity sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g== "@types/figlet@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@types/figlet/-/figlet-1.2.0.tgz" - integrity sha512-TDZkNpYfkc3X8yv7w1QBziZmmxzNfGKX+YjeNkMpmSiNV0QOdNf9G5cEZB3FH1/oaqpSQEdxuDzURdju2L3lng== - -"@types/glob@*": - version "7.1.3" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz" - integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + version "1.12.0" + resolved "https://registry.npmjs.org/@types/figlet/-/figlet-1.12.0.tgz#93815add81d19f318cfcf61ff606afaf704e87ff" + integrity sha512-tPv140QqwGL4Jot2fzTxC6Oy8BVdHEZe4SJDlRuRkywfksv8kMCbTYvtuN9mJCm41HlgRhwb5rRaiH6FE5Hm9g== dependencies: - "@types/minimatch" "*" - "@types/node" "*" + figlet "*" -"@types/http-cache-semantics@^4.0.2": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" - integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== - -"@types/inquirer@^6.5.0": - version "6.5.0" - resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz" - integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw== - dependencies: - "@types/through" "*" - rxjs "^6.4.0" +"@types/http-cache-semantics@^4.2.0": + version "4.2.0" + resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#f6a7788f438cbfde15f29acad46512b4c01913b3" + integrity sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q== -"@types/js-yaml@^3.12.5": - version "3.12.5" - resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz" - integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww== +"@types/js-yaml@^4.0.9": + version "4.0.9" + resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" + integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== -"@types/json-schema@^7.0.3": - version "7.0.5" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/listr@^0.14.2": - version "0.14.2" - resolved "https://registry.npmjs.org/@types/listr/-/listr-0.14.2.tgz" - integrity sha512-wCipMbQr3t2UHTm90LldVp+oTBj1TX6zvpkCJcWS4o8nn6kS8SN93oUvKJAgueIRZ5M36yOlFmScqBxYH8Ajig== + version "0.14.10" + resolved "https://registry.npmjs.org/@types/listr/-/listr-0.14.10.tgz#c675fca3ae2030c2ce52fa9b2839fdb6de47568b" + integrity sha512-g5/EazbMACM1JrM/oGtW28vXo4Bv0E03/FIsqqIXbR/CztuHEgR8QAJDrB1Y5bQH7/ISQh0jNV3v65NM29HgAQ== dependencies: "@types/node" "*" rxjs "^6.5.1" "@types/lodash-es@^4.17.7": - version "4.17.7" - resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" - integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== + version "4.17.12" + resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b" + integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== dependencies: "@types/lodash" "*" "@types/lodash@*": - version "4.14.191" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz" - integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + version "4.17.27" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.27.tgz#15fb73275b64dbfe49e2ae8376bb469b352a47a7" + integrity sha512-VenMRv/eKNrspX9v3H4dbmjsrnCOYdYBG3kxXKk3dG6X+urBGcj2Prww3xw1U5K4FV/mE4h5GbWd0szEKf+9ew== "@types/mime-types@^2.1.0": - version "2.1.0" - resolved "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz" - integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM= + version "2.1.4" + resolved "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz#93a1933e24fed4fb9e4adc5963a63efcbb3317a2" + integrity sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w== -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/mocha@^10.0.1": + version "10.0.10" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz#91f62905e8d23cbd66225312f239454a23bebfa0" + integrity sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q== -"@types/minimatch@^3.0.4": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== +"@types/node@*": + version "26.6.6" + resolved "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz#9ed7b5817e728ed9216ef7c5b7d373fe3b777104" + integrity sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog== + dependencies: + undici-types "~8.9.0" -"@types/mocha@^10.0.1": - version "10.0.1" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== - -"@types/node@*", "@types/node@^18.11.18": - version "18.15.11" - resolved "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz" - integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== - -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== - -"@types/node@>=13.7.0": - version "20.2.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.3.tgz#b31eb300610c3835ac008d690de6f87e28f9b878" - integrity sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw== - -"@types/node@^18.0.0": - version "18.16.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.14.tgz#ab67bb907f1146afc6fedb9ce60ae8a99c989631" - integrity sha512-+ImzUB3mw2c5ISJUq0punjDilUQ5GnUim0ZRvchHIWJmOC0G+p0kzhXBqj6cDjK0QdPFwzrHWgrJp3RPvCG5qg== - -"@types/node@^22.7.5": +"@types/node@22.7.5": version "22.7.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + resolved "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== dependencies: undici-types "~6.19.2" -"@types/prettier@^2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.5.tgz" - integrity sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ== - -"@types/request@^2.48.5": - version "2.48.5" - resolved "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz" - integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== +"@types/node@^20.19.0": + version "20.19.43" + resolved "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz#fcecf580ba42a0db55cf404c372c97973c376c97" + integrity sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA== dependencies: - "@types/caseless" "*" - "@types/node" "*" - "@types/tough-cookie" "*" - form-data "^2.5.0" + undici-types "~6.21.0" -"@types/retry@*": - version "0.12.0" - resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== +"@types/prettier@^2.1.5": + version "2.7.3" + resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== -"@types/rimraf@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz" - integrity sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ== - dependencies: - "@types/glob" "*" - "@types/node" "*" +"@types/retry@*": + version "0.12.5" + resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.5.tgz#f090ff4bd8d2e5b940ff270ab39fd5ca1834a07e" + integrity sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw== "@types/semver@^7.3.1": - version "7.3.1" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.1.tgz" - integrity sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag== - dependencies: - "@types/node" "*" - -"@types/ssh2@*": - version "1.11.11" - resolved "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.11.tgz" - integrity sha512-LdnE7UBpvHCgUznvn2fwLt2hkaENcKPFqOyXGkvyTLfxCXBN6roc1RmECNYuzzbHePzD3PaAov5rri9hehzx9Q== - dependencies: - "@types/node" "^18.11.18" + version "7.8.0" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.8.0.tgz#0bfe3ec51f5e9615bc317174cd5b88ea08b7fc2f" + integrity sha512-1mAINjtQCXXeLkJ9ehXkwOcBpqtLxiVtKhpUf83DdRNdQKV0iXZpaHYqRr7nj+wvxuJzoAmAwXI+sCNMv1CzLQ== "@types/tar-fs@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@types/tar-fs/-/tar-fs-2.0.0.tgz" - integrity sha512-3H2HmxuT1OCZYXi1KG5xIjbpv97JjdLSRByH13YhHK8lr+GaJndJ91IuQfHxn23BQRaWHf2LTnlHPQcQDzt8vw== + version "2.0.4" + resolved "https://registry.npmjs.org/@types/tar-fs/-/tar-fs-2.0.4.tgz#7c7502d281d436db0ad0f78282acef71da02a292" + integrity sha512-ipPec0CjTmVDWE+QKr9cTmIIoTl7dFG/yARCM5MqK8i6CNLIG1P8x4kwDsOQY1ChZOZjH0wO9nvfgBvWl4R3kA== dependencies: "@types/node" "*" "@types/tar-stream" "*" "@types/tar-stream@*": - version "2.1.0" - resolved "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.1.0.tgz" - integrity sha512-s1UQxQUVMHbSkCC0X4qdoiWgHF8DoyY1JjQouFsnk/8ysoTdBaiCHud/exoAZzKDbzAXVc+ah6sczxGVMAohFw== - dependencies: - "@types/node" "*" - -"@types/through@*": - version "0.0.30" - resolved "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz" - integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== + version "3.1.5" + resolved "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-3.1.5.tgz#b8084b982b1f4464fec86832bbad08d7f509e6b8" + integrity sha512-zCUA6CSDw0t2cpQiZixpyzfubpeuVZmBr5wztvuCG4bhy7reX/9wGXdZxEzz2CjMFLQ32UPR/01jzUUSRJeCeQ== dependencies: "@types/node" "*" -"@types/tough-cookie@*": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz" - integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== - "@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + version "21.0.3" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^17.0.24": - version "17.0.24" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz" - integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + version "17.0.35" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.5.0.tgz" - integrity sha512-m4erZ8AkSjoIUOf8s4k2V1xdL2c1Vy0D3dN6/jC9d7+nEqjY3gxXCkgi3gW/GAxPaA4hV8biaCoTVdQmfAeTCQ== - dependencies: - "@typescript-eslint/experimental-utils" "3.5.0" - debug "^4.1.1" - functional-red-black-tree "^1.0.1" - regexpp "^3.0.0" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.5.0.tgz" - integrity sha512-zGNOrVi5Wz0jcjUnFZ6QUD0MCox5hBuVwemGCew2qJzUX5xPoyR+0EzS5qD5qQXL/vnQ8Eu+nv03tpeFRwLrDg== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/types" "3.5.0" - "@typescript-eslint/typescript-estree" "3.5.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@^3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.5.0.tgz" - integrity sha512-sU07VbYB70WZHtgOjH/qfAp1+OwaWgrvD1Km1VXqRpcVxt971PMTU7gJtlrCje0M+Sdz7xKAbtiyIu+Y6QdnVA== - dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "3.5.0" - "@typescript-eslint/types" "3.5.0" - "@typescript-eslint/typescript-estree" "3.5.0" - eslint-visitor-keys "^1.1.0" - -"@typescript-eslint/types@3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.5.0.tgz" - integrity sha512-Dreqb5idi66VVs1QkbAwVeDmdJG+sDtofJtKwKCZXIaBsINuCN7Jv5eDIHrS0hFMMiOvPH9UuOs4splW0iZe4Q== - -"@typescript-eslint/typescript-estree@3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.5.0.tgz" - integrity sha512-Na71ezI6QP5WVR4EHxwcBJgYiD+Sre9BZO5iJK2QhrmRPo/42+b0no/HZIrdD1sjghzlYv7t+7Jis05M1uMxQg== - dependencies: - "@typescript-eslint/types" "3.5.0" - "@typescript-eslint/visitor-keys" "3.5.0" - debug "^4.1.1" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/visitor-keys@3.5.0": - version "3.5.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.5.0.tgz" - integrity sha512-7cTp9rcX2sz9Z+zua9MCOX4cqp5rYyFD5o8LlbSpXrMTXoRdngTtotRZEkm8+FNMHPWYFhitFK+qt/brK8BVJQ== - dependencies: - eslint-visitor-keys "^1.1.0" - -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^7.2.0: - version "7.3.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz" - integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== - -acorn@^8.4.1: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -aes-js@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.3.tgz#da2253f0ff03a0b3a9e445c8cbdf78e7fda7d48c" - integrity sha512-/xJX0/VTPcbc5xQE2VUP91y1xN8q/rDfhEzLm+vLc3hYvb5+qHCnpJRuFcrKn63zumK/sCwYYzhG8HP78JYSTA== +"@typescript-eslint/eslint-plugin@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.1.tgz#95e29de63ce7ed793eb1c6efd9f8b802ce808262" + integrity sha512-5CokTWXpmbylfFabsbvHC0CAw3XLaGnoa+nFJX5FR592h/LoZsENUE6p/rg5xvkKrFEXz6pYmgI29AgXc2N3BQ== + dependencies: + "@eslint-community/regexpp" "^4.12.2" + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/type-utils" "8.72.1" + "@typescript-eslint/utils" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" + ignore "^7.0.5" + natural-compare "^1.4.0" + ts-api-utils "^2.5.0" + +"@typescript-eslint/parser@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.1.tgz#7370b68dadc3819b9aac68ea340bd8b43ee62379" + integrity sha512-ZGwZP4OCfyA0AQTpEAMWz+rtX01DRhQWW5hB0ucKDEIX5U7jdmPSaMx94rQfaPAQzIYz2BimOgKOJtjfpRFQ9g== + dependencies: + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" + debug "^4.4.3" + +"@typescript-eslint/project-service@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.1.tgz#1d09902a9c23f6cfab779e5acc78a45abf540add" + integrity sha512-fAuVMkwdO/huI8nyo/WKnNKf6Gag93S56Rh3Ts5mGcavwSdaN8tRg1gCeIGX8PF+nzp1BjGfO4gHhGzW1J6jTg== + dependencies: + "@typescript-eslint/tsconfig-utils" "^8.72.1" + "@typescript-eslint/types" "^8.72.1" + debug "^4.4.3" + +"@typescript-eslint/scope-manager@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.1.tgz#a0fb4dfe5aa2b0149b7a2d1fd00d947992b13067" + integrity sha512-lC/t6eMCZZQAAKZEYGL6RDVSuFehpdmMT6h+nJIjIa6oylN/PwDgDVtEIbB7O9xFfZYtZAYLoLlDNWKJhtF+uQ== + dependencies: + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" + +"@typescript-eslint/tsconfig-utils@8.72.1", "@typescript-eslint/tsconfig-utils@^8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.1.tgz#07394c85095ee38455e76bc221ba23650af73e44" + integrity sha512-e4D5R5vpeAEPBxT2BAzsFQL3sbwyeeeo5+aczgNSRK1V734jE7pTqaGFU+fXapWEQwnZbpFaTn32+Z8DwS6OTg== + +"@typescript-eslint/type-utils@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.1.tgz#f1f592f63bd9726de21191aae3ccf64a813914b8" + integrity sha512-iY2wlmyrXJmx4yxUGP3aYCFF3cA/6ShddOKmLU2dx7LnEykbAM8WThlxZEfd1NddqceF6eJmZUayxx9oKIYNlg== + dependencies: + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + "@typescript-eslint/utils" "8.72.1" + debug "^4.4.3" + ts-api-utils "^2.5.0" + +"@typescript-eslint/types@8.72.1", "@typescript-eslint/types@^8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.1.tgz#067d8f738c294611e33a1425ae43ac9b9c2f24e3" + integrity sha512-LmE5IhQet1BWOWEXqBrVtBPsMAOQ6Nzk35d+WLh3mk4EUF33sqlfxjio1MdYeSvKSG5skactKKuixBIKXhL4Rw== + +"@typescript-eslint/typescript-estree@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.1.tgz#e93b9cc3a56bf12f5fed857bb8f4963cce7924ee" + integrity sha512-DAlUoUV93hIvrtIQLwCbmZQYVZwOMhiHJrOVUUIWicFZaIYjTRqlY3I/NZevfkLmSqkNHRu2qYDcq9lrn16oOQ== + dependencies: + "@typescript-eslint/project-service" "8.72.1" + "@typescript-eslint/tsconfig-utils" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/visitor-keys" "8.72.1" + debug "^4.4.3" + minimatch "^10.2.2" + semver "^7.7.3" + tinyglobby "^0.2.15" + ts-api-utils "^2.5.0" + +"@typescript-eslint/utils@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.1.tgz#f210c1bf4a25aa1306df80c702ed30bbbc9b4d3d" + integrity sha512-5v5liypurJBFHCBNqh/RjsymAD+VWcE0djuGY/BUqp5fC3Qn+luWDEksjuTtWjPn6i5zQlUtkZCRG/CYG0yCkA== + dependencies: + "@eslint-community/eslint-utils" "^4.9.1" + "@typescript-eslint/scope-manager" "8.72.1" + "@typescript-eslint/types" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + +"@typescript-eslint/visitor-keys@8.72.1": + version "8.72.1" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.1.tgz#c7aec9883b44ef795f1b8200df81d9d44d355de7" + integrity sha512-SB8xqipSzZHUePCCLNeYxqnxq83X61/qzNhjQGbTfjxGZIeOEP7tBgWYX05Tcd6CgE02WdTJnh5b8kMZJ/+bnQ== + dependencies: + "@typescript-eslint/types" "8.72.1" + eslint-visitor-keys "^5.0.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.16.0: + version "8.19.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz#6b26fd97ce1cc9dc50bdf7ad305e9f1384d4f28a" + integrity sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw== aes-js@4.0.0-beta.5: version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + resolved "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== -ajv@^6.10.0, ajv@^6.10.2: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^6.5.5: - version "6.12.3" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz" - integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== +ajv@^6.14.0: + version "6.15.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492" + integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -862,327 +818,235 @@ ajv@^6.5.5: uri-js "^4.2.2" ajv@^8.17.1: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" - integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + version "8.20.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz#304b3636add88ba7d936760dd50ece006dea95f9" + integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== dependencies: fast-deep-equal "^3.1.3" fast-uri "^3.0.1" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^3.2.1: - version "3.2.4" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-escapes@^7.0.0: + version "7.3.0" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz#5395bb74b2150a4a1d6e3c2565f4aeca78d28627" + integrity sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg== + dependencies: + environment "^1.0.0" + ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== ansi-regex@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - -ansi-regex@^5.0.0, ansi-regex@^5.0.1: +ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.2.2: + version "6.5.0" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.5.0.tgz#83f070e17628d0031eb33eb2315a72d8bb11d2a0" + integrity sha512-zhvbbbdt1kbw7EJ9OQoxmQcuaNR9P5kTj7e/YdmOSU10aHWbycofJxA6jKfoEy3vlLdctOF9ZHaxLtmSm998wQ== + ansi-styles@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" +ansi-styles@^6.2.1: + version "6.2.3" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" + integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== any-observable@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz" + resolved "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== -any-signal@^3.0.0, any-signal@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/any-signal/-/any-signal-3.0.1.tgz#49cae34368187a3472e31de28fb5cb1430caa9a6" - integrity sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -asn1@^0.2.4, asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +argparse@^3.0.3: + version "3.0.4" + resolved "https://registry.npmjs.org/argparse/-/argparse-3.0.4.tgz#ba802dd75fdc3d5bdcb4339b713d62c6c5d4565d" + integrity sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA== assertion-error@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - async-retry@^1.2.3: - version "1.3.1" - resolved "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz" - integrity sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA== + version "1.3.3" + resolved "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== dependencies: - retry "0.12.0" + retry "0.13.1" asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +b4a@^1.6.4, b4a@^1.8.1, b4a@^1.9.0: + version "1.9.0" + resolved "https://registry.npmjs.org/b4a/-/b4a-1.9.0.tgz#6336313b6e76b299c397afa68676ec6ebc788845" + integrity sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ== -bl@^4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz" - integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" +balanced-match@^4.0.2: + version "4.0.4" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" + integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== + +bare-buffer@^3.0.0: + version "3.7.1" + resolved "https://registry.npmjs.org/bare-buffer/-/bare-buffer-3.7.1.tgz#dcd2fb7907cfe7df0cf18cb752a04ae2a41140bc" + integrity sha512-cIjZnSO+y89ykVX9x96OVnA6tGORBn7vGJ/e3PCbBHMEyfMNG/ixzOS0lLa6saMlWcs69bSKjxFyDwjK152OMg== + +bare-events@^2.5.4, bare-events@^2.7.0: + version "2.9.2" + resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.9.2.tgz#01d377b64c3c7167b28b52da7add3221aecf2d7f" + integrity sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA== + +bare-fs@^4.0.1, bare-fs@^4.8.2: + version "4.8.4" + resolved "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.4.tgz#f342288e7e5d9d8e79917078e1f45950507828c5" + integrity sha512-MPC2eyrpbk3A873sK4y6rk+Iv4o2enxTjHZ8zH3HO0mjrpm5XjnguY2XmfidIsDV6vnjpbMBKUAJpV0ISD2SsQ== + dependencies: + bare-events "^2.5.4" + bare-path "^3.0.0" + bare-stream "^2.6.4" + bare-url "^2.2.2" + fast-fifo "^1.3.2" + +bare-path@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/bare-path/-/bare-path-3.1.2.tgz#67261bc74a9ba0105ba139b8638f218c09e8d82e" + integrity sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw== -blob-to-it@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/blob-to-it/-/blob-to-it-2.0.3.tgz#ea76abbe7a158d77683a0b155de5ed8dd4c703f4" - integrity sha512-Z3CAVpJMwB9B/lp+hOGEyD+6Rx690v1EBj37Wf/eF7ltXZEu2ppd2H9w/FFNGlx36PW5tsoynTNt2HwkgNV9hw== +bare-stream@^2.6.4: + version "2.13.4" + resolved "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.4.tgz#61d448a268d1efd992103aae6bd729332f278ac0" + integrity sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA== dependencies: - browser-readablestream-to-it "^2.0.0" + b4a "^1.8.1" + streamx "^2.25.0" + teex "^1.0.1" -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== +bare-url@^2.2.2: + version "2.5.6" + resolved "https://registry.npmjs.org/bare-url/-/bare-url-2.5.6.tgz#7f7a96c459bd432bec43f797c0afca1325cb9b5f" + integrity sha512-iqkXHkW65De+BT14nHLiBFbNuJ/DdMrZaVNJ1IXPctpK6b1olUJ5Qmy8QBvwROajTiGztso2n82kFEvCsNG7Rg== dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" + bare-buffer "^3.0.0" + bare-path "^3.0.0" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" +before-after-hook@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz#cf1447ab9160df6a40f3621da64d6ffc36050cb9" + integrity sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ== -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +brace-expansion@^5.0.12: + version "5.0.12" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz#995fbb4750a77c4d16a7dc942ff2ca6ef8e675ec" + integrity sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ== dependencies: - fill-range "^7.0.1" - -browser-readablestream-to-it@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/browser-readablestream-to-it/-/browser-readablestream-to-it-1.0.3.tgz#ac3e406c7ee6cdf0a502dd55db33bab97f7fba76" - integrity sha512-+12sHB+Br8HIh6VAMVEG5r3UXCyESIgDW7kzk3BjIXa43DVqVwL7GC5TW3jeh+72dtcH99pPVpw0X8i0jt+/kw== - -browser-readablestream-to-it@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/browser-readablestream-to-it/-/browser-readablestream-to-it-2.0.3.tgz#8c08c7c0d98aa1b4098fd19cb147a6028b188470" - integrity sha512-kFLXH4FWJNZbbIEeqZMCYfVPQx6glf3e1mReo3bB3xbn1o/YWbHsYpxIGo2rfNsmPqv7I+Fg4qObvtvbAq4DbA== + balanced-match "^4.0.2" -browser-stdout@1.3.1: +browser-stdout@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer@^5.5.0: - version "5.6.0" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -buffer@^6.0.1, buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buildcheck@~0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" - integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" +byte-counter@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz#c49760b5790e50e942a0d57a57b3fc0e94488dcc" + integrity sha512-jheRLVMeUKrDBjVw2O5+k4EvR4t9wtxHL+bo/LxfkxsVeuGMy3a5SEGgXdAFA4FSzTrU8rQXQIrsZ3oBq5a0pQ== cacheable-lookup@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== -cacheable-request@^10.2.8: - version "10.2.14" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" - integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== +cacheable-request@^13.0.12: + version "13.0.19" + resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.19.tgz#2c8a3b6b4cc37ea6906cc182f5b838e5822b2f97" + integrity sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg== dependencies: - "@types/http-cache-semantics" "^4.0.2" - get-stream "^6.0.1" - http-cache-semantics "^4.1.1" - keyv "^4.5.3" + "@types/http-cache-semantics" "^4.2.0" + get-stream "^9.0.1" + http-cache-semantics "^4.2.0" + keyv "^5.6.0" mimic-response "^4.0.0" - normalize-url "^8.0.0" - responselike "^3.0.0" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + normalize-url "^8.1.1" + responselike "^4.0.2" -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +cacheable@^2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz#d142d41043e5a865f6053cc70ef4e3ad068bd5ce" + integrity sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g== + dependencies: + "@cacheable/memory" "^2.2.0" + "@cacheable/utils" "^2.5.0" + hookified "^1.15.0" + keyv "^5.6.0" + qified "^0.10.1" -cborg@^1.10.0, cborg@^1.9.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.2.tgz#83cd581b55b3574c816f82696307c7512db759a1" - integrity sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug== +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" chai@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.0.tgz#648cf2d8b5d16f32646612e22ffd12dc617ef960" - integrity sha512-kDZ7MZyM6Q1DhR9jy7dalKohXQ2yrlXkk59CR52aRKxJrobmlBNqnFQxX9xOX8w+4mz8SYlKJa/7D7ddltFXCw== + version "5.3.3" + resolved "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz#dd3da955e270916a4bd3f625f4b919996ada7e06" + integrity sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw== dependencies: assertion-error "^2.0.1" - check-error "^2.0.0" + check-error "^2.1.1" deep-eql "^5.0.1" loupe "^3.1.0" pathval "^2.0.0" chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1190,101 +1054,69 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chardet@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz#005d664f2cbd4961888d2e2c32c5a69e59d8eec4" + integrity sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA== -check-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.0.0.tgz#589a4f201b6256fd93a2d165089fe43d2676d8c6" - integrity sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog== - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" +check-error@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz#2427361117b70cca8dc89680ead32b157019caf5" + integrity sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA== -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chokidar@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz#949c126a9238a80792be9a0265934f098af369a5" + integrity sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw== + dependencies: + readdirp "^5.0.0" cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== dependencies: restore-cursor "^2.0.0" +cli-cursor@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" + integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== + dependencies: + restore-cursor "^5.0.0" + cli-progress@^3.8.2: - version "3.8.2" - resolved "https://registry.npmjs.org/cli-progress/-/cli-progress-3.8.2.tgz" - integrity sha512-qRwBxLldMSfxB+YGFgNRaj5vyyHe1yMpVeDL79c+7puGujdKJHQHydgqXDcrkvQgJ5U/d3lpf6vffSoVVUftVQ== + version "3.12.0" + resolved "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz#807ee14b66bcc086258e444ad0f19e7d42577942" + integrity sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A== dependencies: - colors "^1.1.2" - string-width "^4.2.0" + string-width "^4.2.3" cli-truncate@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz" - integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha512-f4r4yJnbT++qUPI9NR4XLDLq41gQ+uqnPItWG0F5ZkehuNiTTa3EY0S4AqTSUOeJ7/zU41oWPQSNkW5BqPL9bg== dependencies: slice-ansi "0.0.4" string-width "^1.0.1" -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== cliui@^8.0.1: version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -1293,1302 +1125,743 @@ cliui@^8.0.1: code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colors@^1.1.2: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cpu-features@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.7.tgz#81ba93e1d0a729fd25132a54c3ff689c37b542f7" - integrity sha512-fjzFmsUKKCrC9GrM1eQTvQx18e+kjXFzjRLvJPNEDjk31+bJ6ZiV6uchv/hzbzXVIgbWdrEyyX1IFKwse65+8w== - dependencies: - buildcheck "~0.0.6" - nan "^2.17.0" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +commander@^14.0.0: + version "14.0.3" + resolved "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz#425d79b48f9af82fcd9e4fc1ea8af6c5ec07bbc2" + integrity sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw== -cross-fetch@^3.1.5: - version "3.1.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.6.tgz#bae05aa31a4da760969756318feeee6e70f15d6c" - integrity sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g== - dependencies: - node-fetch "^2.6.11" +content-type@^3.0.0: + version "3.1.1" + resolved "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz#7c80289f1a03ae3fc1f8399c388d22ae44d1394f" + integrity sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA== -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -dag-jose@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/dag-jose/-/dag-jose-4.0.0.tgz#4e65f62af58dd5203b2b094eb52142ffe0cdec1d" - integrity sha512-tw595L3UYoOUT9dSJPbBEG/qpRpw24kRZxa5SLRnlnr+g5L7O8oEs1d3W5TiVA1oJZbthVsf0Vi3zFN66qcEBA== - dependencies: - "@ipld/dag-cbor" "^9.0.0" - multiformats "^11.0.0" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - date-fns@^1.27.2: version "1.30.1" - resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== -debug@4.3.4, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^4.0.1, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== +debug@^4.3.1, debug@^4.3.2, debug@^4.3.5, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: - ms "^2.1.1" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + ms "^2.1.3" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== +decompress-response@^10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz#d8abd2a4c136c3b99b49a08d1f9a709fe35675a4" + integrity sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q== dependencies: - mimic-response "^3.1.0" + mimic-response "^4.0.0" deep-eql@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.1.tgz#21ea2c0d561a4d08cdd99c417ac584e0fb121385" - integrity sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw== + version "5.0.2" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -defer-to-connect@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -deprecation@^2.0.0: - version "2.3.1" - resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +diff@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz#297c31cd7c280f13dfe335791ec2063bd4a73a6f" + integrity sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dotenv@^16.6.1: + version "16.6.1" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020" + integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow== -dns-over-http-resolver@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/dns-over-http-resolver/-/dns-over-http-resolver-2.1.1.tgz#a3ff3fd7614cea7a4b72594eaf12fb3c85080456" - integrity sha512-Lm/eXB7yAQLJ5WxlBGwYfBY7utduXPZykcSmcG6K7ozM0wrZFvxZavhT6PqI0kd/5CUTfev/RrEFQqyU4CGPew== - dependencies: - debug "^4.3.1" - native-fetch "^4.0.2" - receptacle "^1.3.2" - undici "^5.12.0" - -docker-modem@^3.0.0: - version "3.0.8" - resolved "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz" - integrity sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ== - dependencies: - debug "^4.1.1" - readable-stream "^3.5.0" - split-ca "^1.0.1" - ssh2 "^1.11.0" - -dockerode@^3.3.5: - version "3.3.5" - resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz" - integrity sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA== - dependencies: - "@balena/dockerignore" "^1.0.2" - docker-modem "^3.0.0" - tar-fs "~2.0.1" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -electron-fetch@^1.7.2: - version "1.9.1" - resolved "https://registry.yarnpkg.com/electron-fetch/-/electron-fetch-1.9.1.tgz#e28bfe78d467de3f2dec884b1d72b8b05322f30f" - integrity sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA== +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== dependencies: - encoding "^0.1.13" + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" elegant-spinner@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz" - integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + resolved "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ== -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +emoji-regex@^10.3.0: + version "10.6.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz#bf3d6e8f7f8fd22a65d9703475bc0147357a6b0d" + integrity sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== +end-of-stream@^1.1.0: + version "1.4.5" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== dependencies: once "^1.4.0" -enquirer@^2.3.5: - version "2.3.5" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz" - integrity sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA== +environment@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1" + integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== + +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz#a2d0b373205724dfa525d23b0c3e1b1ca582c99b" + integrity sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw== dependencies: - ansi-colors "^3.2.1" + es-errors "^1.3.0" -err-code@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" - integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + +esbuild@~0.28.0: + version "0.28.2" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz#0f43bd1bad955b72d24e2261e3abe5957ccf0816" + integrity sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.28.2" + "@esbuild/android-arm" "0.28.2" + "@esbuild/android-arm64" "0.28.2" + "@esbuild/android-x64" "0.28.2" + "@esbuild/darwin-arm64" "0.28.2" + "@esbuild/darwin-x64" "0.28.2" + "@esbuild/freebsd-arm64" "0.28.2" + "@esbuild/freebsd-x64" "0.28.2" + "@esbuild/linux-arm" "0.28.2" + "@esbuild/linux-arm64" "0.28.2" + "@esbuild/linux-ia32" "0.28.2" + "@esbuild/linux-loong64" "0.28.2" + "@esbuild/linux-mips64el" "0.28.2" + "@esbuild/linux-ppc64" "0.28.2" + "@esbuild/linux-riscv64" "0.28.2" + "@esbuild/linux-s390x" "0.28.2" + "@esbuild/linux-x64" "0.28.2" + "@esbuild/netbsd-arm64" "0.28.2" + "@esbuild/netbsd-x64" "0.28.2" + "@esbuild/openbsd-arm64" "0.28.2" + "@esbuild/openbsd-x64" "0.28.2" + "@esbuild/openharmony-arm64" "0.28.2" + "@esbuild/sunos-x64" "0.28.2" + "@esbuild/win32-arm64" "0.28.2" + "@esbuild/win32-ia32" "0.28.2" + "@esbuild/win32-x64" "0.28.2" escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + version "3.2.0" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -eslint-scope@^5.0.0, eslint-scope@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-scope@^9.1.2: + version "9.1.2" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz#b9de6ace2fab1cff24d2e58d85b74c8fcea39802" + integrity sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ== dependencies: - eslint-visitor-keys "^1.1.0" + "@types/esrecurse" "^4.3.1" + "@types/estree" "^1.0.8" + esrecurse "^4.3.0" + estraverse "^5.2.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.2.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^7.3.1: - version "7.3.1" - resolved "https://registry.npmjs.org/eslint/-/eslint-7.3.1.tgz" - integrity sha512-cQC/xj9bhWUcyi/RuMbRtC3I0eW8MH0jhRELSvpKYkWep3C6YZ2OkvcvJVUeO6gcunABmzptbXBuDoXsjHmfTA== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.0" - eslint-utils "^2.0.0" - eslint-visitor-keys "^1.2.0" - espree "^7.1.0" - esquery "^1.2.0" +eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint-visitor-keys@^5.0.0, eslint-visitor-keys@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz#9e3c9489697824d2d4ce3a8ad12628f91e9f59be" + integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== + +eslint@^10.14.0: + version "10.14.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-10.14.0.tgz#b7574df08d11d9eaa04222f09606674a0ea51db9" + integrity sha512-T0pNsxkb9IKmtQjhpK3d7nWOpFv+YHuMbTJnSVMoQblF0onvXfErrtp4V1jHtsQPan7dKaGVD0q1WCXnzMF31A== + dependencies: + "@eslint-community/eslint-utils" "^4.8.0" + "@eslint-community/regexpp" "^4.12.2" + "@eslint/config-array" "^0.23.5" + "@eslint/config-helpers" "^0.7.0" + "@eslint/core" "^1.2.1" + "@eslint/plugin-kit" "^0.7.3" + "@humanfs/node" "^0.16.8" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.2" + "@types/estree" "^1.0.6" + ajv "^6.14.0" + cross-spawn "^7.0.6" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^9.1.2" + eslint-visitor-keys "^5.0.1" + espree "^11.2.0" + esquery "^1.7.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + fast-deep-equal "^3.1.3" + file-entry-cache "11.1.5 || >11.1.6 <12" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.14" - minimatch "^3.0.4" + minimatch "^10.2.6" natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -esm@^3.2.25: - version "3.2.25" - resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" - integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== - -espree@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz" - integrity sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw== - dependencies: - acorn "^7.2.0" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.2.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + optionator "^0.9.3" -esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== +espree@^11.2.0: + version "11.2.0" + resolved "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz#01d5e47dc332aaba3059008362454a8cc34ccaa5" + integrity sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw== dependencies: - estraverse "^5.1.0" + acorn "^8.16.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^5.0.1" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esquery@^1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" + integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== dependencies: - estraverse "^4.1.0" + estraverse "^5.1.0" -estraverse@^4.1.0, estraverse@^4.1.1: +esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" -estraverse@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz" - integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -ethers@6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.3.0.tgz#c61efaafa2bd9a4d9f0c799d932ef3b5cd4bd37d" - integrity sha512-CKFYvTne1YT4S1glTiu7TgGsj0t6c6GAD7evrIk8zbeUb6nK8dcUPAiAWM8uDX/1NmRTvLM9+1Vnn49hwKtEzw== - dependencies: - "@adraffy/ens-normalize" "1.9.0" - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.7.1" - aes-js "4.0.0-beta.3" - tslib "2.4.0" - ws "8.5.0" - -ethers@^6.9.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.10.0.tgz#20f3c63c60d59a993f8090ad423d8a3854b3b1cd" - integrity sha512-nMNwYHzs6V1FR3Y4cdfxSQmNgZsRj1RiTU25JwvnJLmyzw9z3SKxNc2XKDuiXXo/v9ds5Mp9m6HBabgYQQ26tA== +ethers@^6.17.0: + version "6.17.0" + resolved "https://registry.npmjs.org/ethers/-/ethers-6.17.0.tgz#ad85ee1fc45fe2d95cb1e21c4e3ff9f7f1b093cc" + integrity sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang== dependencies: - "@adraffy/ens-normalize" "1.10.0" + "@adraffy/ens-normalize" "1.11.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" + "@types/node" "22.7.5" aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" + tslib "2.7.0" + ws "8.21.0" -eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== +events-universal@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz#b56a84fd611b6610e0a2d0f09f80fdf931e2dfe6" + integrity sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw== dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + bare-events "^2.7.0" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-fifo@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.2.0.tgz#2ee038da2468e8623066dee96958b0c1763aa55a" - integrity sha512-NcvQXt7Cky1cNau15FWy64IjuO8X0JijhTBBrJj1YlxlDfRkJXNaK9RFUjwpfDPzMdv7wB38jr53l9tkNLxnWg== +fast-fifo@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748" - integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== + version "3.1.9" + resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz#f1deba822b1d6ac79da2f860e872a63470cff203" + integrity sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ== -figlet@^1.2.3: - version "1.4.0" - resolved "https://registry.npmjs.org/figlet/-/figlet-1.4.0.tgz" - integrity sha512-CxxIjEKHlqGosgXaIA+sikGDdV6KZOOlzPJnYuPgQlOSHZP5h9WIghYI30fyXnwEVeSH7Hedy72gC6zJrFC+SQ== +fdir@^6.5.0: + version "6.5.0" + resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + +figlet@*, figlet@^1.2.3: + version "1.12.0" + resolved "https://registry.npmjs.org/figlet/-/figlet-1.12.0.tgz#3e9c3a12f112db9479bd5ae4b87bc2b337b9a1af" + integrity sha512-Ith3WsUi0N/EqGt+0/F6XnWhT04sohhH2tT0Dq7GdUmWbMTIoCbg2Jq9qKggmTO62ST5kRCfB311EmIMbizGyA== + dependencies: + commander "^14.0.0" figures@^1.7.0: version "1.7.0" - resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ== dependencies: escape-string-regexp "^1.0.5" object-assign "^4.1.0" figures@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA== dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +"file-entry-cache@11.1.5 || >11.1.6 <12": + version "11.1.5" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz#c8210eb055de63e68685ccfb6a017e386d4577d0" + integrity sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q== dependencies: - flat-cache "^2.0.1" + flat-cache "^6.1.23" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" +find-up-simple@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz#18fb90ad49e45252c4d7fca56baade04fa3fca1e" + integrity sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ== -find-up@5.0.0: +find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" path-exists "^4.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^6.1.23: + version "6.1.23" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz#735dc888c271868d7301b3bbb8edba5028afb61d" + integrity sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + cacheable "^2.5.0" + flatted "^3.4.2" + hookified "^1.15.0" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data-encoder@^2.1.2: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" - integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== +flatted@^3.4.2: + version "3.4.4" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz#aeeca2a506303f0cee61c59e6c9f2a88d2f29fc6" + integrity sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q== -form-data@^2.5.0: - version "2.5.1" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" +form-data-encoder@^4.0.2: + version "4.1.0" + resolved "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz#497cedc94810bd5d53b99b5d4f6c152d5cbc9db2" + integrity sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw== -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== +form-data@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz#28e864e1b786dbebb68db1f452f9635278665827" + integrity sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" - mime-types "^2.1.12" + es-set-tostringtag "^2.1.0" + hasown "^2.0.4" + mime-types "^2.1.35" -form-data@~2.3.2: +fsevents@~2.3.3: version "2.3.3" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" - integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== - -get-iterator@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82" - integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg== - -get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-east-asian-width@^1.0.0, get-east-asian-width@^1.3.1: + version "1.7.0" + resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz#7ee99f0bd5ab7c622002deeabba232923726d1d4" + integrity sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q== -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= +get-intrinsic@^1.2.6: + version "1.3.0" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== dependencies: - assert-plus "^1.0.0" + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== +get-stream@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" + integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== dependencies: - is-glob "^4.0.1" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -got@^12.6.1: - version "12.6.1" - resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" - integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== - 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" + "@sec-ant/readable-stream" "^0.4.1" + is-stream "^4.0.1" -graphql-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-6.1.0.tgz#f4eb2107967af3c7a5907eb3131c671eac89be4f" - integrity sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw== +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: - "@graphql-typed-document-node/core" "^3.2.0" - cross-fetch "^3.1.5" + is-glob "^4.0.3" -graphql@^16.6.0: - version "16.6.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" - integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== - -hamt-sharding@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/hamt-sharding/-/hamt-sharding-3.0.2.tgz#a3fba1e4e6b58469388a0e1458768c78c0cd95f6" - integrity sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw== +glob@^13.0.0, glob@^14.0.2: + version "14.0.3" + resolved "https://registry.npmjs.org/glob/-/glob-14.0.3.tgz#71e124649b3e28fdb09bdb07ef478b10c68fd6e1" + integrity sha512-A1vjIwC3qpdCso45Iw127gnp7sPhqgY8lUQhDrArIs+GbmfaaVPFuoyy7WyLT9EPZCRZ7j7aLdwUhQmHWesEow== dependencies: - sparse-array "^1.3.1" - uint8arrays "^4.0.2" + minimatch "^11.0.2" + minipass "^7.1.3" + path-scurry "^3.0.0" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== +got@^14.6.6: + version "14.6.6" + resolved "https://registry.npmjs.org/got/-/got-14.6.6.tgz#5adf7f576f89de8e291fd782e8b277f9bcc8e6c0" + integrity sha512-QLV1qeYSo5l13mQzWgP/y0LbMr5Plr5fJilgAIwgnwseproEbtNym8xpLsDzeZ6MWXgNE6kdWGBjdh3zT/Qerg== dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" + "@sindresorhus/is" "^7.0.1" + byte-counter "^0.1.0" + cacheable-lookup "^7.0.0" + cacheable-request "^13.0.12" + decompress-response "^10.0.0" + form-data-encoder "^4.0.2" + http2-wrapper "^2.2.1" + keyv "^5.5.3" + lowercase-keys "^3.0.0" + p-cancelable "^4.0.1" + responselike "^4.0.2" + type-fest "^4.26.1" has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== dependencies: ansi-regex "^2.0.0" has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -he@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -http-cache-semantics@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" - integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== +has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + has-symbols "^1.0.3" -http2-wrapper@^2.1.10: - version "2.2.1" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" - integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.2.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== +hashery@^1.4.0, hashery@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz#4ba82ad54911ac617467870845d57a9fe508a400" + integrity sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ== dependencies: - safer-buffer ">= 2.1.2 < 3" + hookified "^1.15.0" -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== +hasown@^2.0.2, hasown@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003" + integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A== dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" + function-bind "^1.1.2" -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +hookified@^1.15.0, hookified@^1.15.1: + version "1.15.1" + resolved "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz#b1fafeaa5489cdc29cb85546a8f837ed4ffbbcb6" + integrity sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg== -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +hookified@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz#1d024ac1668973dd5bcc4a96ab9ccdb7639ef8d4" + integrity sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA== -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +http-cache-semantics@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.3.0.tgz#09eead3b16c6d85552857cc3fbd888d8353a2aaf" + integrity sha512-M5t5LlJpS1UHMjvwRQVdFHvPISGeLAxNcrWuJkeGh0KxsqCHZ1O3NXZU/8x7cD0BDcGW8kapxMKTvwlqrNkHkA== -image-size@^0.8.1: - version "0.8.3" - resolved "https://registry.npmjs.org/image-size/-/image-size-0.8.3.tgz" - integrity sha512-SMtq1AJ+aqHB45c3FsB4ERK0UCiA2d3H1uq8s+8T0Pf8A3W4teyBQyaFaktH6xvZqh+npwlKU7i4fJo0r7TYTg== +http2-wrapper@^2.2.1: + version "2.2.4" + resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.4.tgz#6aee653365fe19051e970cc466e179929d43cef0" + integrity sha512-y5jx4isTOKEC5Hu1lswc+IxytGlqDmwF1qJtk9qIS8l1KVxuHO5g522UfmErt1H2pMcH/xq+KiFQUB8aVWIABA== dependencies: - queue "6.0.1" + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== +iconv-lite@^0.7.0: + version "0.7.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz#84ee12f963e7de50bc01a13e160a078b3b0f415f" + integrity sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ== dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + safer-buffer ">= 2.1.2 < 3.0.0" -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= +ignore@^5.2.0: + version "5.3.2" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" +ignore@^7.0.5: + version "7.0.14" + resolved "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz#a52b081dfb4d77e947e04d5f9e320b16f1873959" + integrity sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ== -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +image-size@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + resolved "https://registry.npmjs.org/image-size/-/image-size-2.0.4.tgz#bbc1933173e4ee1adbbdf9d4958ded15fdb710e3" + integrity sha512-QRUkFFsRV/6fuESxb9Vkq+a0LkSrgKXuc2NEqfikiXxxN/G3tjWt5EVUlMaImRBZRZK/jRBEbYvpPYZL8t08Zw== -inquirer@^6.2.1: - version "6.5.2" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -interface-blockstore@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/interface-blockstore/-/interface-blockstore-5.2.0.tgz#150216529cf56bf43c2aebd3070f4351d1169ef4" - integrity sha512-lLW6fNP3PkBKghK9BsLuV8VMquL/o2lInomrTUizY/p4n7vxzVn3YT7qGTHywZzCcMIBeGMneDApGe21TNkg+g== - dependencies: - interface-store "^5.0.0" - multiformats "^11.0.2" - -interface-datastore@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-7.0.4.tgz#f09ae4e2896f57f876d5d742a59e982fb3f42891" - integrity sha512-Q8LZS/jfFFHz6XyZazLTAc078SSCoa27ZPBOfobWdpDiFO7FqPA2yskitUJIhaCgxNK8C+/lMBUTBNfVIDvLiw== - dependencies: - interface-store "^3.0.0" - nanoid "^4.0.0" - uint8arrays "^4.0.2" - -interface-datastore@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.0.tgz#70076985ac17dcdb35b33c2b0f957480ce6489e1" - integrity sha512-rDMAcpCGxWMubRk2YQuSEHl11bc0xcZeBZzfLvqhoZJdByUWeo7YDJUdgyRKgD6liGXVYirtDkFU9nyn9xl2hg== - dependencies: - interface-store "^5.0.0" - nanoid "^4.0.0" - uint8arrays "^4.0.2" - -interface-datastore@^8.2.0: - version "8.2.3" - resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.3.tgz#491f6e90da963dbbb23d44c97aaae38959a797de" - integrity sha512-5U6BfK7cR4oSngm4pqYZBBAX7tpLI4YCOa3Ifz/EJEaEV2mmlloH5qP8ADWCVFk6vP1MPT925JJkt3kFIi7iWQ== - dependencies: - interface-store "^5.0.0" - nanoid "^4.0.0" - uint8arrays "^4.0.2" - -interface-store@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-3.0.4.tgz#670d95ef45f3b7061d154c3cbfaf39a538167ad7" - integrity sha512-OjHUuGXbH4eXSBx1TF1tTySvjLldPLzRSYYXJwrEQI+XfH5JWYZofr0gVMV4F8XTwC+4V7jomDYkvGRmDSRKqQ== - -interface-store@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-5.1.0.tgz#1735cead844fe452d62c307fafbaaa1d261e6ff3" - integrity sha512-mjUwX3XSoreoxCS3sXS3pSRsGnUjl9T06KBqt/T7AgE9Sgp4diH64ZyURJKnj2T5WmCvTbC0Dm+mwQV5hfLSBQ== - -ipfs-core-types@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/ipfs-core-types/-/ipfs-core-types-0.14.0.tgz#a301d534f5261aad2254da393cb09f9cd36b6742" - integrity sha512-qO1xVO3n5m7scTXXtMz8hDTLdwXInnwqadIDQpXC446BIlaYyRWUvLcFQ2bOjQql9/CPNTaPHzjzr5Y1XxqpJw== - dependencies: - "@ipld/dag-pb" "^4.0.0" - "@libp2p/interface-keychain" "^2.0.0" - "@libp2p/interface-peer-id" "^2.0.0" - "@libp2p/interface-peer-info" "^1.0.2" - "@libp2p/interface-pubsub" "^3.0.0" - "@multiformats/multiaddr" "^11.0.0" - "@types/node" "^18.0.0" - interface-datastore "^7.0.0" - ipfs-unixfs "^9.0.0" - multiformats "^11.0.0" - -ipfs-core-utils@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/ipfs-core-utils/-/ipfs-core-utils-0.18.0.tgz#c528c6cfb231d3a1a0d5420d0a3506615d26f4b4" - integrity sha512-7N/KfsOPGJu9mwN8EQwrW9HXgS5RNM3WUyjIMWk49KlpYmsXectXuC9i6npI1vn1W/oUaIOZt3lHx37jecnepw== - dependencies: - "@libp2p/logger" "^2.0.0" - "@multiformats/multiaddr" "^11.0.0" - "@multiformats/multiaddr-to-uri" "^9.0.1" - any-signal "^3.0.0" - blob-to-it "^2.0.0" - browser-readablestream-to-it "^2.0.0" - err-code "^3.0.1" - ipfs-core-types "^0.14.0" - ipfs-unixfs "^9.0.0" - ipfs-utils "^9.0.13" - it-all "^2.0.0" - it-map "^2.0.0" - it-peekable "^2.0.0" - it-to-stream "^1.0.0" - merge-options "^3.0.4" - multiformats "^11.0.0" - nanoid "^4.0.0" - parse-duration "^1.0.0" - timeout-abort-controller "^3.0.0" - uint8arrays "^4.0.2" - -ipfs-unixfs-exporter@^13.1.5: - version "13.1.5" - resolved "https://registry.yarnpkg.com/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.5.tgz#345ab63c10671af926630447c40059f8d8107533" - integrity sha512-O5aMawsHoe4DaYk5FFil2EPrNOaU3pkHC6qUR5JMnW7es93W3b/RjJoO7AyDL1rpb+M3K0oRu86Yc5wLNQQ8jg== - dependencies: - "@ipld/dag-cbor" "^9.0.0" - "@ipld/dag-pb" "^4.0.0" - "@multiformats/murmur3" "^2.0.0" - err-code "^3.0.1" - hamt-sharding "^3.0.0" - interface-blockstore "^5.0.0" - ipfs-unixfs "^11.0.0" - it-filter "^3.0.2" - it-last "^3.0.2" - it-map "^3.0.3" - it-parallel "^3.0.0" - it-pipe "^3.0.1" - it-pushable "^3.1.0" - multiformats "^11.0.0" - p-queue "^7.3.0" - progress-events "^1.0.0" - uint8arrays "^4.0.2" - -ipfs-unixfs@^11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-11.0.1.tgz#7232e888b15a785aef7a5bd4dedf1861401f3b63" - integrity sha512-SD9dqn14bfgMfkPstsR/2Av3zCzYMj2ntQJab4HZucgX4nNV6K7guZh4Hf3kiL8ONff1Ogft1ekFU083DIKEdQ== - dependencies: - err-code "^3.0.1" - protons-runtime "^5.0.0" - uint8arraylist "^2.4.3" - -ipfs-unixfs@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ipfs-unixfs/-/ipfs-unixfs-9.0.1.tgz#d06e688e07ef4ce08d610337ba2fe8c143c386e7" - integrity sha512-jh2CbXyxID+v3jLml9CqMwjdSS9ZRnsGfQGGPOfem0/hT/L48xUeTPvh7qLFWkZcIMhZtG+fnS1teei8x5uGBg== - dependencies: - err-code "^3.0.1" - protobufjs "^7.0.0" - -ipfs-utils@^9.0.13, ipfs-utils@^9.0.7: - version "9.0.14" - resolved "https://registry.yarnpkg.com/ipfs-utils/-/ipfs-utils-9.0.14.tgz#24f5fda1f4567685eb32bca2543d518f95fd8704" - integrity sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg== - dependencies: - any-signal "^3.0.0" - browser-readablestream-to-it "^1.0.0" - buffer "^6.0.1" - electron-fetch "^1.7.2" - err-code "^3.0.1" - is-electron "^2.2.0" - iso-url "^1.1.5" - it-all "^1.0.4" - it-glob "^1.0.1" - it-to-stream "^1.0.0" - merge-options "^3.0.4" - nanoid "^3.1.20" - native-fetch "^3.0.0" - node-fetch "^2.6.8" - react-native-fetch-api "^3.0.0" - stream-to-it "^0.2.2" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -is-electron@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.2.tgz#3778902a2044d76de98036f5dc58089ac4d80bb9" - integrity sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg== +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ== + +inquirer@^12.11.1: + version "12.11.1" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-12.11.1.tgz#3f5770b9ec926b0909e463e42c766f2664f2cc96" + integrity sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw== + dependencies: + "@inquirer/ansi" "^1.0.2" + "@inquirer/core" "^10.3.2" + "@inquirer/prompts" "^7.10.1" + "@inquirer/type" "^3.0.10" + mute-stream "^2.0.0" + run-async "^4.0.6" + rxjs "^7.8.2" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== +is-fullwidth-code-point@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz#046b2a6d4f6b156b2233d3207d4b5a9783999b98" + integrity sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ== dependencies: - is-extglob "^2.1.1" + get-east-asian-width "^1.3.1" -is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" -is-ipfs@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/is-ipfs/-/is-ipfs-8.0.1.tgz#23aefd086d32a7fce7b180bc55bf71313a641415" - integrity sha512-hoBSElmPath3aDdtaOpVZsuCh2SXTqvLML+H75S7iDgKdqNmENJ6tsRucP1HLfpqEyZ/uIlj/+ZBxIC/F8B5Eg== - dependencies: - "@multiformats/mafmt" "^11.0.3" - "@multiformats/multiaddr" "^11.0.0" - iso-url "^1.1.3" - multiformats "^11.0.0" - uint8arrays "^4.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - is-observable@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz" + resolved "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== dependencies: symbol-observable "^1.1.0" -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-path-inside@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz#805aeb62c47c1b12fc3fd13bfb3ed1e7430071db" + integrity sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA== is-promise@^2.1.0: version "2.2.2" - resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz" + resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== is-stream@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-stream@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" + integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -iso-url@^1.1.3, iso-url@^1.1.5: - version "1.2.1" - resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-1.2.1.tgz#db96a49d8d9a64a1c889fc07cc525d093afb1811" - integrity sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng== - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -it-all@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/it-all/-/it-all-1.0.6.tgz#852557355367606295c4c3b7eff0136f07749335" - integrity sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A== - -it-all@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-all/-/it-all-2.0.1.tgz#45d530ecf6e13fb81d7ba583cdfd55ffdb376b05" - integrity sha512-9UuJcCRZsboz+HBQTNOau80Dw+ryGaHYFP/cPYzFBJBFcfDathMYnhHk4t52en9+fcyDGPTdLB+lFc1wzQIroA== - -it-filter@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/it-filter/-/it-filter-3.0.2.tgz#19ddf6185ea21d417e6075d5796c799fa2633b69" - integrity sha512-Hhzp5anX7tmKOBqTPasBYTPlq7l4Xk4lMBfLB5GfKZnL9WCc6pr8M9Waud4nHh3s9neb4xwDWk7KQsEapgWyJw== - dependencies: - it-peekable "^3.0.0" - -it-first@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-first/-/it-first-2.0.1.tgz#75d66b254c385ae3a1906def060a69006a437cef" - integrity sha512-noC1oEQcWZZMUwq7VWxHNLML43dM+5bviZpfmkxkXlvBe60z7AFRqpZSga9uQBo792jKv9otnn1IjA4zwgNARw== - -it-glob@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/it-glob/-/it-glob-1.0.2.tgz#bab9b04d6aaac42884502f3a0bfee84c7a29e15e" - integrity sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q== - dependencies: - "@types/minimatch" "^3.0.4" - minimatch "^3.0.4" - -it-last@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-last/-/it-last-2.0.1.tgz#a6f3253459cb77e917aeada3b2c4ae9f3e66c64b" - integrity sha512-uVMedYW0wa2Cx0TAmcOCLbfuLLII7+vyURmhKa8Zovpd+aBTMsmINtsta2n364wJ5qsEDBH+akY1sUtAkaYBlg== - -it-last@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/it-last/-/it-last-3.0.2.tgz#b012d88d2cc0d1e01eedf2b5114cefd94cef6c9b" - integrity sha512-aWoA5moJ7XSKe7+YuutBKhySroDDWkfjpo+UknekPh1M5YYdK4YNSPDarR+7o/NqRwzazwgzCi2UZzU0oqsprQ== - -it-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-map/-/it-map-2.0.1.tgz#d5251fd6b222d6ee39293d406a3f8fce54fb9220" - integrity sha512-a2GcYDHiAh/eSU628xlvB56LA98luXZnniH2GlD0IdBzf15shEq9rBeb0Rg3o1SWtNILUAwqmQxEXcewGCdvmQ== - -it-map@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/it-map/-/it-map-3.0.3.tgz#42be39fc68dc9b0d70cfd8ac4b8311d4b5cd7f22" - integrity sha512-Yf89GJYeYUZb2NZzWkvFHm3IBXlxro74i2vGRmpf8BYau3BhlaS37ieDenJEdYzkTGJhL/EbM1jPPw/KGVVVIw== - dependencies: - it-peekable "^3.0.0" - -it-merge@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-3.0.1.tgz#20cc293593586e5afcbfed8ba88a94def5ccfcfa" - integrity sha512-I6hjU1ABO+k3xY1H6JtCSDXvUME88pxIXSgKeT4WI5rPYbQzpr98ldacVuG95WbjaJxKl6Qot6lUdxduLBQPHA== - dependencies: - it-pushable "^3.1.0" - -it-parallel@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/it-parallel/-/it-parallel-3.0.3.tgz#b02f1d6459418c7253ecf13e367111560a616491" - integrity sha512-Q5KmdvERHCOLDcgKqrzQ+yiMCdG6H9h7ZL3Zjx/Tx9xhZy8txSKoy+EiCgWZFs0rfYvxJhk6UkOpKLzJ1zM9ZA== - dependencies: - p-defer "^4.0.0" - -it-peekable@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-peekable/-/it-peekable-2.0.1.tgz#1e118610473aa511efc70f3bb7a7066178728dd3" - integrity sha512-fJ/YTU9rHRhGJOM2hhQKKEfRM6uKB9r4yGGFLBHqp72ACC8Yi6+7/FhuBAMG8cpN6mLoj9auVX7ZJ3ul6qFpTA== - -it-peekable@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/it-peekable/-/it-peekable-3.0.1.tgz#530953f735359c10503e961c059602f8a366a1a5" - integrity sha512-5zBfkf6e+YoxxWV0YDXMwdQKnc7eeTX6xo3WYPm/8dIoctIiDnddInRWOW+83W/8/76sbnpWqqsO4gSyXandeQ== - -it-pipe@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/it-pipe/-/it-pipe-3.0.1.tgz#b25720df82f4c558a8532602b5fbc37bbe4e7ba5" - integrity sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA== - dependencies: - it-merge "^3.0.0" - it-pushable "^3.1.2" - it-stream-types "^2.0.1" - -it-pushable@^3.0.0, it-pushable@^3.1.0, it-pushable@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.1.3.tgz#b6f4a1e0236502f12b5661b40468b629799baf0e" - integrity sha512-f50iQ85HISS6DaWCyrqf9QJ6G/kQtKIMf9xZkgZgyOvxEQDfn8OfYcLXXquCqgoLboxQtAW1ZFZyFIAsLHDtJw== - -it-stream-types@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/it-stream-types/-/it-stream-types-1.0.5.tgz#9c72e6adefdea9dac69d0a28fbea783deebd508d" - integrity sha512-I88Ka1nHgfX62e5mi5LLL+oueqz7Ltg0bUdtsUKDe9SoUqbQPf2Mp5kxDTe9pNhHQGs4pvYPAINwuZ1HAt42TA== - -it-stream-types@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/it-stream-types/-/it-stream-types-2.0.1.tgz#69cb4d7e79e707b8257a8997e02751ccb6c3af32" - integrity sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg== - -it-to-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/it-to-stream/-/it-to-stream-1.0.0.tgz#6c47f91d5b5df28bda9334c52782ef8e97fe3a4a" - integrity sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA== - dependencies: - buffer "^6.0.3" - fast-fifo "^1.0.0" - get-iterator "^1.0.2" - p-defer "^3.0.0" - p-fifo "^1.0.0" - readable-stream "^3.6.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +js-yaml@^4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz#8e44fb14a2643c59726bb15787b5f1512cb3d3fb" + integrity sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA== dependencies: argparse "^2.0.1" -js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== +js-yaml@^5.0.0: + version "5.5.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-5.5.0.tgz#ec843f09ffb2a54b6758a41eee109a1815d16442" + integrity sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + argparse "^3.0.3" json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" +json-with-bigint@^3.5.12: + version "3.5.12" + resolved "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz#9f6bf722a9847ed72fa9b217b2b66181227c454c" + integrity sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w== -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== +keyv@^5.5.3, keyv@^5.6.0: + version "5.6.0" + resolved "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz#03044074c6b4d072d0a62c7b9fa649537baf0105" + integrity sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw== dependencies: - json-buffer "3.0.1" - -kubo-rpc-client@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/kubo-rpc-client/-/kubo-rpc-client-3.0.1.tgz#61e4c64ccab6bf1bb6147dc8c45a423b95638fa7" - integrity sha512-2SMH/eCZlwR/4e9Aqr0HC1gJvCDTsgBRWRdu4LjHLrRwGsmDAl32vK4PkwkKfYwgJMHY3lgA6eZzaOLzrPwxFg== - dependencies: - "@ipld/dag-cbor" "^9.0.0" - "@ipld/dag-json" "^10.0.0" - "@ipld/dag-pb" "^4.0.0" - "@libp2p/crypto" "^1.0.11" - "@libp2p/logger" "^2.0.5" - "@libp2p/peer-id" "^2.0.0" - "@multiformats/multiaddr" "^11.1.5" - any-signal "^3.0.1" - dag-jose "^4.0.0" - err-code "^3.0.1" - ipfs-core-utils "^0.18.0" - ipfs-utils "^9.0.7" - it-first "^2.0.0" - it-last "^2.0.0" - merge-options "^3.0.4" - multiformats "^11.0.0" - parse-duration "^1.0.2" - stream-to-it "^0.2.4" - uint8arrays "^4.0.3" + "@keyv/serialize" "^1.1.1" levn@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2596,12 +1869,12 @@ levn@^0.4.1: listr-silent-renderer@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz" - integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + resolved "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha512-L26cIFm7/oZeSNVhWB6faeorXhMg4HNlb/dS/7jHhr708jxlXrtrBWo4YUxZQkc6dGoxEAe6J/D3juTRBUzjtA== listr-update-renderer@^0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz" + resolved "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== dependencies: chalk "^1.1.3" @@ -2615,7 +1888,7 @@ listr-update-renderer@^0.5.0: listr-verbose-renderer@^0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz" + resolved "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== dependencies: chalk "^2.4.1" @@ -2625,7 +1898,7 @@ listr-verbose-renderer@^0.5.0: listr@^0.14.3: version "0.14.3" - resolved "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz" + resolved "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== dependencies: "@samverschueren/stream-to-observable" "^0.3.0" @@ -2640,1240 +1913,723 @@ listr@^0.14.3: locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" -lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - -lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" +lodash-es@^4.18.1: + version "4.18.1" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz#b962eeb80d9d983a900bf342961fb7418ca10b1d" + integrity sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A== log-symbols@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz" - integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha512-mmPrW0Fh2fxOzdBbFv4g1m6pR72haFLPJ2G5SJEELf1y+iaQrDG6cWCPjy54RHYbZAt7X+ls690Kw62AdWXBzQ== dependencies: chalk "^1.0.0" log-update@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz" - integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + resolved "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg== dependencies: ansi-escapes "^3.0.0" cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -long@^5.0.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== +log-update@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" + integrity sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w== + dependencies: + ansi-escapes "^7.0.0" + cli-cursor "^5.0.0" + slice-ansi "^7.1.0" + strip-ansi "^7.1.0" + wrap-ansi "^9.0.0" loupe@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.0.tgz#46ef1a4ffee73145f5c0a627536d754787c1ea2a" - integrity sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg== - dependencies: - get-func-name "^2.0.1" + version "3.2.1" + resolved "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz#0095cf56dc5b7a9a7c08ff5b1a8796ec8ad17e76" + integrity sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ== lowercase-keys@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +lru-cache@^11.0.0: + version "11.5.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz#a7767b4034e35269562d2b9da2b185b5df70c421" + integrity sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg== -merge-options@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7" - integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ== - dependencies: - is-plain-obj "^2.1.0" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.24, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== +mime-types@^2.1.24, mime-types@^2.1.35: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.44.0" + mime-db "1.52.0" mimic-fn@^1.0.0: version "1.2.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== +mimic-function@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" + integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== mimic-response@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== +minimatch@^10.2.2, minimatch@^10.2.4, minimatch@^10.2.6, minimatch@^11.0.1, minimatch@^11.0.2: + version "11.0.4" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-11.0.4.tgz#3ed156790c2754647ee94dab305a3f93cd16481e" + integrity sha512-/UJ1dEoVQTjPNDh6SGlUo+ueLMmoHTas4q+8yaAR/5t6nLAIiBDJtoYUh20IYleix7ehiQkgczb84PE3uzHkxg== dependencies: - brace-expansion "^2.0.1" + "@isaacs/nonrecursive-glob-match" "^1.0.3" + brace-expansion "^5.0.12" -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.5: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha@^10.2.0: - version "10.2.0" - resolved "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" +minipass@^7.1.2, minipass@^7.1.3: + version "7.1.3" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b" + integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A== + +mocha@^12.0.3: + version "12.0.3" + resolved "https://registry.npmjs.org/mocha/-/mocha-12.0.3.tgz#f3022f5684f5a8306323dd5ab4d0f881a90cd031" + integrity sha512-beammieDdiWdkjANWeWPpkxUROYGi5FN88fPOkLiticz7HTg3Y+Pho3EYE6SUdcuWnZ3h2WD8EXCA55JF4o6wg== + dependencies: + browser-stdout "^1.3.1" + chokidar "^5.0.0" + debug "^4.3.5" + diff "^9.0.0" + find-up-simple "^1.0.1" + glob "^13.0.0" + is-path-inside "^4.0.0" + is-unicode-supported "^0.1.0" + js-yaml "^5.0.0" + minimatch "^10.2.2" + ms "^2.1.3" + picocolors "^1.1.1" + serialize-javascript "^7.1.1" + strip-json-comments "^5.0.3" + supports-color "^8.1.1" + workerpool "^10.0.0" moment@^2.27.0: - version "2.29.4" - resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + version "2.31.0" + resolved "https://registry.npmjs.org/moment/-/moment-2.31.0.tgz#6e19184e8005a9dfc61c9351263d4d6ea2ace7aa" + integrity sha512-0acOTfMiWOheYS4eoWb80yYMb/JLvVv9SHbs2PehaDzfUG0Bw855SKyk0IKTnPGa5+U2bmi3W68l1+sGLX/pvw== -ms@2.1.3: +ms@^2.1.3: version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multiformats@^11.0.0, multiformats@^11.0.2: - version "11.0.2" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-11.0.2.tgz#b14735efc42cd8581e73895e66bebb9752151b60" - integrity sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg== - -murmurhash3js-revisited@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz#6bd36e25de8f73394222adc6e41fa3fac08a5869" - integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nan@^2.16.0, nan@^2.17.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -nanoid@^3.1.20: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -nanoid@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" - integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== - -native-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-3.0.0.tgz#06ccdd70e79e171c365c75117959cf4fe14a09bb" - integrity sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw== - -native-fetch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-4.0.2.tgz#75c8a44c5f3bb021713e5e24f2846750883e49af" - integrity sha512-4QcVlKFtv2EYVS5MBgsGX5+NWKtbDbIECdUXDBGDMAZXq3Jkv9zf+y8iS7Ub8fEdga3GpYeazp9gauNqXHJOCg== +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -node-fetch@^2.6.11, node-fetch@^2.6.8: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1.1.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -normalize-url@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.2.tgz#3b343a42f837e4dae2b01917c04e8de3782e9170" - integrity sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw== +normalize-url@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz#751a20c8520e5725404c06015fea21d7567f25ef" + integrity sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ== number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== object-assign@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== dependencies: mimic-fn "^1.0.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +onetime@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz#9f16c92d8c9ef5120e3acd9dd9957cceecc1ab60" + integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== + dependencies: + mimic-function "^5.0.0" + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-cancelable@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" - integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + word-wrap "^1.2.5" -p-defer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" - integrity sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw== - -p-defer@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-4.0.0.tgz#8082770aeeb10eb6b408abe91866738741ddd5d2" - integrity sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ== - -p-fifo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-fifo/-/p-fifo-1.0.0.tgz#e29d5cf17c239ba87f51dde98c1d26a9cfe20a63" - integrity sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A== - dependencies: - fast-fifo "^1.0.0" - p-defer "^3.0.0" +p-cancelable@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz#2d1edf1ab8616b72c73db41c4bc9ecdd10af640e" + integrity sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg== p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-map@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz" + resolved "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== -p-queue@^7.3.0: - version "7.3.4" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-7.3.4.tgz#7ef7d89b6c1a0563596d98adbc9dc404e9ed4a84" - integrity sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg== - dependencies: - eventemitter3 "^4.0.7" - p-timeout "^5.0.2" - -p-timeout@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-5.1.0.tgz#b3c691cf4415138ce2d9cfe071dba11f0fee085b" - integrity sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-duration@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/parse-duration/-/parse-duration-1.0.3.tgz#b6681f5edcc2689643b34c09ea63f86f58a35814" - integrity sha512-o6NAh12na5VvR6nFejkU0gpQ8jmOY9Y9sTU2ke3L3G/d/3z8jqmbBbeyBGHU73P4JLXfc7tJARygIK3WGIkloA== - -parse-duration@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parse-duration/-/parse-duration-1.1.0.tgz#5192084c5d8f2a3fd676d04a451dbd2e05a1819c" - integrity sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ== - path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-scurry@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-3.0.0.tgz#384894267bb8d1889242d176433f91ae1eec5cbb" + integrity sha512-1pTbQqH1wIwMi/eleQ5leFTTCkzFsPcgXNjwOA8YGGW/W4/kHT3dssE7Z6NH+zuqNLOzOB0uaD61yl7cAcVhgg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + pathval@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" - integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + version "2.0.1" + resolved "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz#8855c5a2899af072d6ac05d11e46045ad0dc605d" + integrity sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.4: + version "4.0.7" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz#6313360034ccb36b3dc61ecbdff78121f90fe21f" + integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA== prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz" - integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== - -progress-events@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/progress-events/-/progress-events-1.0.0.tgz#34f5e8fdb5dae3561837b22672d1e02277bb2109" - integrity sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -protobufjs@^7.0.0: - version "7.2.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2" - integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/node" ">=13.7.0" - long "^5.0.0" - -protons-runtime@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/protons-runtime/-/protons-runtime-5.0.0.tgz#1eb3c78637ff02cc90bb030e3bff6f0402109c25" - integrity sha512-QqjGnPGkpvbzq0dITzhG9DVK10rRIHf7nePcU2QQVVpFGuYbwrOWnvGSvei1GcceAzB9syTz6vHzvTPmGRR0PA== - dependencies: - protobufjs "^7.0.0" - uint8arraylist "^2.4.3" - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + version "2.8.8" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + version "3.0.4" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz#1f313430527fa8b905622ebd22fe1444e757ab3c" + integrity sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA== dependencies: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -queue@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/queue/-/queue-6.0.1.tgz" - integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg== +qified@^0.10.1: + version "0.10.1" + resolved "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz#0640bf21bbe6ca540db290ad8f5fde4d870b8bda" + integrity sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA== dependencies: - inherits "~2.0.3" + hookified "^2.1.1" quick-lru@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -react-native-fetch-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/react-native-fetch-api/-/react-native-fetch-api-3.0.0.tgz#81e1bb6562c292521bc4eca52fe1097f4c1ebab5" - integrity sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA== - dependencies: - p-defer "^3.0.0" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^3.5.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -receptacle@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/receptacle/-/receptacle-1.3.2.tgz#a7994c7efafc7a01d0e2041839dab6c4951360d2" - integrity sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A== - dependencies: - ms "^2.1.1" - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" +readdirp@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz#520bca06f9d1ae1b96cc0800dbe84b983d19422c" + integrity sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== resolve-alpn@^1.2.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -responselike@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" - integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== +responselike@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz#d99a1105aeca5909c1e93156a839c7f3173e26c2" + integrity sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA== dependencies: lowercase-keys "^3.0.0" restore-cursor@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== dependencies: onetime "^2.0.0" signal-exit "^3.0.2" -retimer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/retimer/-/retimer-3.0.0.tgz#98b751b1feaf1af13eb0228f8ea68b8f9da530df" - integrity sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA== - -retry@0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== +restore-cursor@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" + integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== dependencies: - glob "^7.1.3" + onetime "^7.0.0" + signal-exit "^4.1.0" -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" +retry@0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -run-async@^2.2.0: - version "2.4.1" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-async@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz#d53b86acb71f42650fe23de2b3c1b6b6b34b9294" + integrity sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ== -rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.1: - version "6.5.5" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz" - integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== +rxjs@^6.3.3, rxjs@^6.5.1: + version "6.6.7" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +rxjs@^7.8.2: + version "7.8.2" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + dependencies: + tslib "^2.1.0" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^7.2.1, semver@^7.3.2: - version "7.3.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -semver@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" +semver@^7.5.0, semver@^7.6.0, semver@^7.7.3: + version "7.8.6" + resolved "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz#67c0cda133a3ceb6f70b803e67625bf969000424" + integrity sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" +serialize-javascript@^7.1.1: + version "7.1.4" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.4.tgz#477af55bdec0d831fa3b209245f673217fd27380" + integrity sha512-FqlEuoTq/zRmA4Lg6aOqyH3lCHbUtCB0bmHCeFniX2GBdDqMJM3FwdvEhlE5Pim1dlt2FfBdVPmUNNiGhhKqpw== shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== slice-ansi@0.0.4: version "0.0.4" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz" - integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== +slice-ansi@^7.1.0: + version "7.1.2" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz#adf7be70aa6d72162d907cd0e6d5c11f507b5403" + integrity sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^6.2.1" + is-fullwidth-code-point "^5.0.0" source-map-support@^0.5.19: - version "0.5.19" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" source-map@^0.6.0: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sparse-array@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/sparse-array/-/sparse-array-1.3.2.tgz#0e1a8b71706d356bc916fe754ff496d450ec20b0" - integrity sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg== - -split-ca@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz" - integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -ssh2@^1.11.0: - version "1.11.0" - resolved "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz" - integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== +streamx@^2.12.5, streamx@^2.25.0, streamx@^2.28.1: + version "2.28.1" + resolved "https://registry.npmjs.org/streamx/-/streamx-2.28.1.tgz#376cd42a089505a69bec0efdb5189aa45586141f" + integrity sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA== dependencies: - asn1 "^0.2.4" - bcrypt-pbkdf "^1.0.2" - optionalDependencies: - cpu-features "~0.0.4" - nan "^2.16.0" - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stream-to-it@^0.2.2, stream-to-it@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/stream-to-it/-/stream-to-it-0.2.4.tgz#d2fd7bfbd4a899b4c0d6a7e6a533723af5749bd0" - integrity sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ== - dependencies: - get-iterator "^1.0.2" - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + events-universal "^1.0.0" + fast-fifo "^1.3.2" + text-decoder "^1.1.0" string-width@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.1.0, string-width@^2.1.1: +string-width@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== +string-width@^7.0.0: + version "7.2.0" + resolved "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== dependencies: - safe-buffer "~5.2.0" + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1, strip-json-comments@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== +strip-ansi@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz#d22a269522836a627af8d04b5c3fd2c7fa3e32e3" + integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w== dependencies: - has-flag "^4.0.0" + ansi-regex "^6.2.2" + +strip-json-comments@^5.0.3: + version "5.0.3" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz#b7304249dd402ee67fd518ada993ab3593458bcf" + integrity sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw== supports-color@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" symbol-observable@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" + resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.npmjs.org/table/-/table-5.4.6.tgz" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +tar-fs@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.3.tgz#05668cc68a30741c3813f9c16593b8dec7dcbcd1" + integrity sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^4.0.1" + bare-path "^3.0.0" -tar-fs@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz" - integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== +tar-stream@^3.1.5: + version "3.2.2" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.2.tgz#aec7f257e712192a177a93aa0450c2e76855c8be" + integrity sha512-+8NeqHRjQWH9nYlwo2gamAMImZCVzI4UoEgDpWorBt9OEfppiZn+uSkskzQKPWIZyji/C8fpWO7u69G0DX0tbg== dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" + b4a "^1.9.0" + bare-fs "^4.8.2" + fast-fifo "^1.3.2" + streamx "^2.28.1" -tar-fs@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz" - integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== +teex@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz#b8fa7245ef8e8effa8078281946c85ab780a0b12" + integrity sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg== dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" + streamx "^2.12.5" -tar-stream@^2.0.0: - version "2.1.2" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz" - integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== - dependencies: - bl "^4.0.1" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timeout-abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/timeout-abort-controller/-/timeout-abort-controller-3.0.0.tgz#dd57ffca041652c03769904f8d95afd93fb95595" - integrity sha512-O3e+2B8BKrQxU2YRyEjC/2yFdb33slI22WRdUaDx6rvysfi9anloNZyR2q0l6LnePo5qH7gSM7uZtvvwZbc2yA== +text-decoder@^1.1.0: + version "1.2.7" + resolved "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz#5d073a9a74b9c0a9d28dfadcab96b604af57d8ba" + integrity sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ== dependencies: - retimer "^3.0.0" + b4a "^1.6.4" timestring@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/timestring/-/timestring-5.0.1.tgz" + resolved "https://registry.npmjs.org/timestring/-/timestring-5.0.1.tgz#065bd9dda1bcaf7c08ec9a4841569d3bbbb6cf87" integrity sha512-0VfOVpaTYqBMTEpjwcY5mB+72YYjFI44Z5F2q80ZiIyDn5pRJm+rEV1OEM8xfnf5/FdtckcrTERTp9TbrlMMHw== -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== +tinyglobby@^0.2.15: + version "0.2.17" + resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz#562a9a6c9eb2b3b123d39719f9af5bb44fcd7631" + integrity sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g== dependencies: - is-number "^7.0.0" + fdir "^6.5.0" + picomatch "^4.0.4" -tough-cookie@~2.5.0: +ts-api-utils@^2.5.0: version "2.5.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - 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" - -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^1.8.1, tslib@^1.9.0: - version "1.13.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - -tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz#4acd4a155e22734990a5ed1fe9e97f113bcb37c1" + integrity sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA== + +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + +tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0: + version "2.9.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.9.1.tgz#8986213ba2f17f38ba39a7c43d0e565a9134ff5f" + integrity sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA== + +tsx@^4.23.15: + version "4.23.15" + resolved "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz#f53901695685ad567fed0f08532f7782e631c251" + integrity sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw== + dependencies: + esbuild "~0.28.0" + optionalDependencies: + fsevents "~2.3.3" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^4.26.1: + version "4.41.0" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== -typescript@^5.6.3: - version "5.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" - integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== - -uint8arraylist@^2.1.2, uint8arraylist@^2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/uint8arraylist/-/uint8arraylist-2.4.3.tgz#1148aa979b407d382e4eb8d9c8f2b4bf3f5910d5" - integrity sha512-oEVZr4/GrH87K0kjNce6z8pSCzLEPqHNLNR5sj8cJOySrTP8Vb/pMIbZKLJGhQKxm1TiZ31atNrpn820Pyqpow== - dependencies: - uint8arrays "^4.0.2" - -uint8arrays@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.3.tgz#43109c03c4c10d312e7f2e9f4d53e5cd2398c7fd" - integrity sha512-b+aKlI2oTnxnfeSQWV1sMacqSNxqhtXySaH6bflvONGxF8V/fT3ZlYH7z2qgGfydsvpVo4JUgM/Ylyfl2YouCg== +typescript-eslint@^8.72.1: + version "8.72.1" + resolved "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.72.1.tgz#46324b99d4809e986aeb01285cfce28f74b45d14" + integrity sha512-3Li9FfPmQp45nxEtFD1ZCrYFI3cYK5kpyNtmm1H7lMagm8u9sy6PTjy3ytwQZs7KNukOyKFHAZ6z6GjYFeaeXw== dependencies: - multiformats "^11.0.0" + "@typescript-eslint/eslint-plugin" "8.72.1" + "@typescript-eslint/parser" "8.72.1" + "@typescript-eslint/typescript-estree" "8.72.1" + "@typescript-eslint/utils" "8.72.1" -uint8arrays@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.4.tgz#3254e01aeb166a3f35e66e60e4e37002f4ea13fd" - integrity sha512-AOoA66e/A7zoXm1mgzQjGmkWDTvCrS3ttWXLHFtlVAwMobLcaOA7G7WRNNAcyfjjYdFDtkEK6njRDX7hZLIO9Q== - dependencies: - multiformats "^11.0.0" +typescript@~5.9.3: + version "5.9.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== undici-types@~6.19.2: version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== -undici@^5.12.0: - version "5.22.1" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" - integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw== - dependencies: - busboy "^1.6.0" +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== -universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +undici-types@~8.9.0: + version "8.9.0" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz#e240d97c8b5d85e5347ce73d25865c7906c1ec9f" + integrity sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg== + +universal-user-agent@^7.0.0, universal-user-agent@^7.0.2: + version "7.0.3" + resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz#c05870a58125a2dc00431f2df815a77fe69736be" + integrity sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache-lib@^3.0.1: - 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== - -v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== - -varint@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" - integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +workerpool@^10.0.0: + version "10.0.3" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-10.0.3.tgz#e9914112d0169a974fc1b4c2fda00388bbd70b61" + integrity sha512-6z2Iis68Wqth93/G/wJP9u+R3O+d2XTlgWChGCwuT1qLbBsOYueGRZuJ++v3mtDP5KjYdy+WzvWC+VWETSVXJA== wrap-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz" - integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ== dependencies: string-width "^2.1.1" strip-ansi "^4.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^9.0.0, wrap-ansi@^9.0.2: + version "9.0.2" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz#956832dea9494306e6d209eb871643bb873d7c98" + integrity sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww== + dependencies: + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/write/-/write-1.0.3.tgz" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@8.21.0: + version "8.21.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951" + integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^2.2.2: - version "2.3.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.0.tgz#47ebe58ee718f772ce65862beb1db816210589a0" - integrity sha512-8/1wgzdKc7bc9E6my5wZjmdavHLvO/QOmLG1FBugblEvY4IXrLjlViIOmL24HthU042lWTDRO90Fz1Yp66UnMw== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yargs@^17.7.1: - version "17.7.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz" - integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== + version "17.7.3" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz#779dffe6bcafec596a7172e983289a588647faaa" + integrity sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g== dependencies: cliui "^8.0.1" escalade "^3.1.1" @@ -3883,12 +2639,12 @@ yargs@^17.7.1: y18n "^5.0.5" yargs-parser "^21.1.1" -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" + integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==