diff --git a/.attw.json b/.attw.json index ac2579855..e5263d5da 100644 --- a/.attw.json +++ b/.attw.json @@ -1,3 +1,4 @@ { - "ignoreRules": ["cjs-resolves-to-esm"] + "ignoreRules": ["cjs-resolves-to-esm"], + "excludeEntrypoints": ["browser.min.js"] } diff --git a/.github/release-please-config.json b/.github/release-please-config.json index 3317946c5..fdf34c508 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -1,6 +1,7 @@ { + "release-type": "node", + "include-component-in-tag": true, "separate-pull-requests": true, - "bootstrap-sha": "c918ffc59eafa01fbc63d5df11ba621cc1888c64", "changelog-sections": [ { "type": "feat", "section": "Features", "hidden": false }, { "type": "fix", "section": "Fixes", "hidden": false }, @@ -9,6 +10,7 @@ "packages": { "packages/access-client": {}, "packages/blob-index": {}, + "packages/cli": {}, "packages/filecoin-api": {}, "packages/filecoin-client": {}, "packages/capabilities": {}, diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json index d777b71f6..e231c7f15 100644 --- a/.github/release-please-manifest.json +++ b/.github/release-please-manifest.json @@ -1,11 +1,12 @@ { - "packages/access-client": "20.1.0", - "packages/blob-index": "1.0.4", - "packages/filecoin-api": "7.3.2", - "packages/filecoin-client": "3.3.4", - "packages/capabilities": "17.4.0", - "packages/upload-api": "18.1.0", - "packages/upload-client": "17.1.0", - "packages/w3up-client": "16.4.0", - "packages/did-mailto": "2.0.2" + "packages/access-client": "1.0.2", + "packages/blob-index": "1.0.1", + "packages/cli": "1.1.1", + "packages/filecoin-api": "1.1.1", + "packages/filecoin-client": "1.0.2", + "packages/capabilities": "1.2.1", + "packages/upload-api": "1.3.2", + "packages/upload-client": "1.0.4", + "packages/w3up-client": "1.1.4", + "packages/did-mailto": "1.0.1" } diff --git a/.github/workflows/access-client.yml b/.github/workflows/access-client.yml index 6998c2622..80c1da4c7 100644 --- a/.github/workflows/access-client.yml +++ b/.github/workflows/access-client.yml @@ -34,7 +34,7 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm run build - - run: pnpm -r --filter @web3-storage/access run lint - - run: pnpm -r --filter @web3-storage/access run test - - run: pnpm -r --filter @web3-storage/access exec depcheck - - run: pnpm --filter '@web3-storage/access' attw + - run: pnpm -r --filter @storacha/access run lint + - run: pnpm -r --filter @storacha/access run test + - run: pnpm -r --filter @storacha/access exec depcheck + - run: pnpm --filter '@storacha/access' attw diff --git a/.github/workflows/blob-index.yml b/.github/workflows/blob-index.yml index 9712fe68a..27312f9e8 100644 --- a/.github/workflows/blob-index.yml +++ b/.github/workflows/blob-index.yml @@ -32,6 +32,6 @@ jobs: node-version: 18 registry-url: https://registry.npmjs.org/ cache: 'pnpm' - - run: pnpm --filter '@web3-storage/blob-index...' install - - run: pnpm --filter '@web3-storage/blob-index' lint - - run: pnpm --filter '@web3-storage/blob-index' test + - run: pnpm --filter '@storacha/blob-index...' install + - run: pnpm --filter '@storacha/blob-index' lint + - run: pnpm --filter '@storacha/blob-index' test diff --git a/.github/workflows/capabilities.yml b/.github/workflows/capabilities.yml index 1d7725b4a..eabfd8ead 100644 --- a/.github/workflows/capabilities.yml +++ b/.github/workflows/capabilities.yml @@ -29,6 +29,6 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm run build - - run: pnpm -r --filter @web3-storage/capabilities run lint - - run: pnpm -r --filter @web3-storage/capabilities run test - - run: pnpm -r --filter @web3-storage/capabilities exec depcheck + - run: pnpm -r --filter @storacha/capabilities run lint + - run: pnpm -r --filter @storacha/capabilities run test + - run: pnpm -r --filter @storacha/capabilities exec depcheck diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml new file mode 100644 index 000000000..4e662157c --- /dev/null +++ b/.github/workflows/cli.yml @@ -0,0 +1,43 @@ +name: cli +on: + push: + branches: + - main + paths: + - 'packages/cli/**' + - 'packages/eslint-config-w3up/**' + - '.github/workflows/cli.yml' + - 'pnpm-lock.yaml' + pull_request: + paths: + - 'packages/cli/**' + - 'packages/eslint-config-w3up/**' + - '.github/workflows/cli.yml' + - 'pnpm-lock.yaml' +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + node_version: + - 18 + - 20 + defaults: + run: + working-directory: ./packages/cli + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install + uses: pnpm/action-setup@v4 + - name: Setup + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node_version }} + registry-url: https://registry.npmjs.org/ + cache: 'pnpm' + - run: pnpm install + - run: pnpm -r --filter @storacha/cli run lint + - run: pnpm -r --filter @storacha/cli run check + - run: pnpm -r --filter @storacha/cli run test diff --git a/.github/workflows/did-mailto.yml b/.github/workflows/did-mailto.yml index 2142d0862..452d8cb0b 100644 --- a/.github/workflows/did-mailto.yml +++ b/.github/workflows/did-mailto.yml @@ -32,6 +32,6 @@ jobs: node-version: 18 registry-url: https://registry.npmjs.org/ cache: 'pnpm' - - run: pnpm --filter '@web3-storage/did-mailto...' install - - run: pnpm --filter '@web3-storage/did-mailto' lint - - run: pnpm --filter '@web3-storage/did-mailto' test + - run: pnpm --filter '@storacha/did-mailto...' install + - run: pnpm --filter '@storacha/did-mailto' lint + - run: pnpm --filter '@storacha/did-mailto' test diff --git a/.github/workflows/filecoin-api.yml b/.github/workflows/filecoin-api.yml index 492cf6c01..99fb63ce1 100644 --- a/.github/workflows/filecoin-api.yml +++ b/.github/workflows/filecoin-api.yml @@ -44,6 +44,6 @@ jobs: pnpm run --if-present build - name: Lint - run: pnpm -r --filter @web3-storage/filecoin-api run lint + run: pnpm -r --filter @storacha/filecoin-api run lint - name: Test - run: pnpm -r --filter @web3-storage/filecoin-api run test + run: pnpm -r --filter @storacha/filecoin-api run test diff --git a/.github/workflows/filecoin-client.yml b/.github/workflows/filecoin-client.yml index 8fbe6a426..fbb5a49e6 100644 --- a/.github/workflows/filecoin-client.yml +++ b/.github/workflows/filecoin-client.yml @@ -34,6 +34,6 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm run build - - run: pnpm -r --filter @web3-storage/filecoin-client run lint - - run: pnpm -r --filter @web3-storage/filecoin-client run test - - run: pnpm -r --filter @web3-storage/filecoin-client run attw + - run: pnpm -r --filter @storacha/filecoin-client run lint + - run: pnpm -r --filter @storacha/filecoin-client run test + - run: pnpm -r --filter @storacha/filecoin-client run attw diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index c5262b504..280e4aa04 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -35,12 +35,12 @@ jobs: registry-url: 'https://registry.npmjs.org' cache: 'pnpm' - run: pnpm install - - run: pnpm -r --filter @web3-storage/access build - - run: pnpm -r --filter @web3-storage/access run rc || true # this fails because npm does not support workspace protocol so we force it to exit 0 + - run: pnpm -r --filter @storacha/access build + - run: pnpm -r --filter @storacha/access run rc || true # this fails because npm does not support workspace protocol so we force it to exit 0 - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: 'chore(access): Bump access sdk pre release version' - - run: pnpm -r --filter @web3-storage/access publish --tag next --access public + - run: pnpm -r --filter @storacha/access publish --tag next --access public env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} deploy-upload-client: @@ -57,11 +57,11 @@ jobs: registry-url: 'https://registry.npmjs.org' cache: 'pnpm' - run: pnpm install - - run: pnpm -r --filter @web3-storage/upload-client build - - run: pnpm -r --filter @web3-storage/upload-client run rc || true # this fails because npm does not support workspace protocol so we force it to exit 0 + - run: pnpm -r --filter @storacha/upload-client build + - run: pnpm -r --filter @storacha/upload-client run rc || true # this fails because npm does not support workspace protocol so we force it to exit 0 - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: 'chore(client): Bump client pre release version' - - run: pnpm -r --filter @web3-storage/upload-client publish --tag next --access public + - run: pnpm -r --filter @storacha/upload-client publish --tag next --access public env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5828f2116..40b20d55e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,20 +15,18 @@ jobs: outputs: paths_released: ${{ steps.release.outputs.paths_released }} steps: - - uses: google-github-actions/release-please-action@v3 + - uses: googleapis/release-please-action@v4 id: release with: - command: manifest config-file: .github/release-please-config.json manifest-file: .github/release-please-manifest.json - default-branch: main - release-type: node npm: needs: release if: | contains(fromJson(needs.release.outputs.paths_released), 'packages/access-client') || contains(fromJson(needs.release.outputs.paths_released), 'packages/blob-index') || contains(fromJson(needs.release.outputs.paths_released), 'packages/capabilities') || + contains(fromJson(needs.release.outputs.paths_released), 'packages/cli') || contains(fromJson(needs.release.outputs.paths_released), 'packages/did-mailto') || contains(fromJson(needs.release.outputs.paths_released), 'packages/upload-client') || contains(fromJson(needs.release.outputs.paths_released), 'packages/upload-api') || diff --git a/.github/workflows/upload-api.yml b/.github/workflows/upload-api.yml index 27aac10e1..eb95c7731 100644 --- a/.github/workflows/upload-api.yml +++ b/.github/workflows/upload-api.yml @@ -73,7 +73,7 @@ jobs: pnpm run --if-present build - name: Test - run: pnpm -r --filter @web3-storage/upload-api run test + run: pnpm -r --filter @storacha/upload-api run test - name: Dependency check - run: pnpm -r --filter @web3-storage/upload-api exec depcheck + run: pnpm -r --filter @storacha/upload-api exec depcheck diff --git a/.github/workflows/upload-client.yml b/.github/workflows/upload-client.yml index 19a8dc94b..c5e452c42 100644 --- a/.github/workflows/upload-client.yml +++ b/.github/workflows/upload-client.yml @@ -34,6 +34,6 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm run build - - run: pnpm -r --filter @web3-storage/upload-client run lint - - run: pnpm -r --filter @web3-storage/upload-client run test - - run: pnpm -r --filter @web3-storage/upload-client exec depcheck + - run: pnpm -r --filter @storacha/upload-client run lint + - run: pnpm -r --filter @storacha/upload-client run test + - run: pnpm -r --filter @storacha/upload-client exec depcheck diff --git a/.github/workflows/w3up-client.yml b/.github/workflows/w3up-client.yml index be8e554fc..5d11703d6 100644 --- a/.github/workflows/w3up-client.yml +++ b/.github/workflows/w3up-client.yml @@ -1,4 +1,4 @@ -name: w3up-client +name: client on: push: branches: @@ -37,8 +37,8 @@ jobs: node-version: ${{ matrix.node_version }} registry-url: https://registry.npmjs.org/ cache: 'pnpm' - - run: pnpm --filter '@web3-storage/w3up-client...' install - - run: pnpm --filter '@web3-storage/w3up-client' attw + - run: pnpm --filter '@storacha/client...' install + - run: pnpm --filter '@storacha/client' attw - uses: ./packages/w3up-client/.github/actions/test with: w3up-client-dir: ./packages/w3up-client/ diff --git a/.gitignore b/.gitignore index 1a16d11ca..b409b3d95 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ docs .env .next out +*.min.js # debug npm-debug.log* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 699af781c..19f4854fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -Join in. All welcome! web3.storage is open-source. The code is dual-licensed under [MIT + Apache 2.0](license.md) +Join in. All welcome! storacha.network is open-source. The code is dual-licensed under [MIT + Apache 2.0](license.md) This project uses node v18 and `pnpm`. It's a monorepo that use [pnpm workspaces](https://pnpm.io/workspaces) to handle resolving dependencies between the local `packages/*` folders. @@ -13,8 +13,6 @@ We use `pnpm` in this project and commit the `pnpm-lock.yaml` file. ```bash # install all dependencies in the mono-repo pnpm install -# setup git hooks -npx simple-git-hooks # setup environment variables cp .env.tpl .env ``` diff --git a/README.md b/README.md index 1b22d2414..434e888be 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# `w3up` +# Upload Service -This repo implements the web3.storage UCAN protocol [specifications](https://github.com/storacha/specs). +This repo implements the storacha.network UCAN protocol [specifications](https://github.com/storacha/specs). -It's the core of the web3.storage server and client implementations. +It's the core of the storacha.network server and client implementations. ## Usage -Store your files with web3.storage and retrieve them via their unique Content ID. Our tools make it simple to hash your content locally, so you can verify the service only ever stores the exact bytes you asked us to. Pick the method of using web3.storage that works for you! +Store your files with storacha.network and retrieve them via their unique Content ID. Our tools make it simple to hash your content locally, so you can verify the service only ever stores the exact bytes you asked us to. Pick the method of using storacha.network that works for you! ### Website -Visit https://console.web3.storage and upload right from the website. +Visit https://console.storacha.network and upload right from the website. -Under the hood it uses the web3.storage client that we publish to npm to chunk and hash your files to calculate the root IPFS CID **in your browser** before sending them to https://up.web3.storage. +Under the hood it uses the storacha.network client that we publish to npm to chunk and hash your files to calculate the root IPFS CID **in your browser** before sending them to https://up.storacha.network. Once uploaded you can fetch your data from any IPFS gateway via [`https://w3s.link/ipfs/`](https://w3s.link/ipfs/bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy) ### Command Line -Install [`@web3-storage/w3cli`](https://github.com/storacha/w3cli#readme) globally, authorize it to act on your behalf, create a space and upload your files. It calculates the root CID for your files locally before sending them to web3.storage. +Install [`@web3-storage/w3cli`](https://github.com/storacha/w3cli#readme) globally, authorize it to act on your behalf, create a space and upload your files. It calculates the root CID for your files locally before sending them to storacha.network. **shell** ```shell @@ -38,14 +38,14 @@ Run `w3 --help` or have a look at https://github.com/storacha/w3cli to find out ### JS Client -Add the [`@web3-storage/w3up-client`](https://www.npmjs.com/package/@web3-storage/w3up-client) module into your project with `npm i @web3-storage/w3up-client` and upload a single file with [`client.uploadFile`](https://github.com/storacha/w3up/blob/main/packages/w3up-client/README.md#uploadfile) or many with [`client.uploadDirectory`](https://github.com/storacha/w3up/blob/main/packages/w3up-client/README.md#uploaddirectory). +Add the [`@storacha/client`](https://www.npmjs.com/package/@storacha/client) module into your project with `npm i @storacha/client` and upload a single file with [`client.uploadFile`](https://github.com/storacha/upload-service/blob/main/packages/w3up-client/README.md#uploadfile) or many with [`client.uploadDirectory`](https://github.com/storacha/upload-service/blob/main/packages/w3up-client/README.md#uploaddirectory). If you've already got a space you can upload like this: **node.js** ```js import { filesFromPaths } from 'files-from-path' -import * as Client from '@web3-storage/w3up-client' +import * as Client from '@storacha/client' const [,,yourEmail, pathToAdd] = process.argv @@ -61,13 +61,13 @@ console.log(`IPFS CID: ${cid}`) console.log(`Gateway URL: https://w3s.link/ipfs/${cid}`) ``` -See https://web3.storage/docs/w3up-client for a guide to using the js client for the first time. +See https://docs.storacha.network/w3up-client for a guide to using the js client for the first time. For an interactive command line adventure into the using w3up check out `learnyouw3up` here https://github.com/storacha/learnyouw3up ### GitHub Action -The Action [`add-to-web3`](https://github.com/marketplace/actions/add-to-web3) wraps [`w3cli`](https://github.com/storacha/w3cli) to let you add files to web3.storage from your GitHub Workflows. +The Action [`add-to-web3`](https://github.com/marketplace/actions/add-to-web3) wraps [`w3cli`](https://github.com/storacha/w3cli) to let you add files to storacha.network from your GitHub Workflows. **github-workflow.yaml** ```yaml @@ -90,9 +90,9 @@ To generate a `secret_key` and delegate permissions to it as a `proof` to use in ## Contributing -All welcome! web3.storage is open-source. See the [contributing guide](./CONTRIBUTING.md) +All welcome! storacha.network is open-source. See the [contributing guide](./CONTRIBUTING.md) -This project uses node v18 and `pnpm`. It's a monorepo that uses [pnpm workspaces](https://pnpm.io/workspaces) to handle resolving dependencies between the local [`packages`](https://github.com/storacha/w3up/tree/main/packages) +This project uses node v18 and `pnpm`. It's a monorepo that uses [pnpm workspaces](https://pnpm.io/workspaces) to handle resolving dependencies between the local [`packages`](https://github.com/storacha/upload-service/tree/main/packages) ## License diff --git a/docusaurus.config.js b/docusaurus.config.js index ea0cb4a0c..ec4ad9661 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -2,9 +2,9 @@ // to generate docusaurus-compatible markdown from typedoc output. const config = { - title: 'Web3.Storage Documentation', + title: 'Storacha Documentation', tagline: 'The simple file storage service for IPFS and Filecoin', - url: 'https://docs.web3.storage', + url: 'https://docs.storacha.network', baseUrl: '/', onBrokenLinks: 'warn', onBrokenMarkdownLinks: 'warn', diff --git a/packages/access-client/CHANGELOG.md b/packages/access-client/CHANGELOG.md index 4063e9872..dca17b882 100644 --- a/packages/access-client/CHANGELOG.md +++ b/packages/access-client/CHANGELOG.md @@ -1,5 +1,105 @@ # Changelog +## [1.0.2](https://github.com/storacha/upload-service/compare/access-v1.0.1...access-v1.0.2) (2025-01-22) + + +### Fixes + +* type error ([a1e09c2](https://github.com/storacha/upload-service/commit/a1e09c26ee69cb0ad18c5b8e5e28c4846782b608)) + + +### Other Changes + +* update uint8arrays dependency ([a36b06f](https://github.com/storacha/upload-service/commit/a36b06f92677854f9bb819c0d7b6425d5b70e62c)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/access-v1.0.0...access-v1.0.1) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## 1.0.0 (2024-12-19) + + +### ⚠ BREAKING CHANGES + +* **upload-api:** integrate agent store for idempotence & invocation/receipt persistence ([#1444](https://github.com/storacha/upload-service/issues/1444)) +* delegated capabilities required to use `uploadFile`, `uploadDirectory` and `uploadCAR` have changed. In order to use these methods your agent will now need to be delegated `blob/add`, `index/add`, `filecoin/offer` and `upload/add` capabilities. Note: no code changes are required. +* coupon ([#1136](https://github.com/storacha/upload-service/issues/1136)) +* tweak readmes to get release-please to bump major version ([#1102](https://github.com/storacha/upload-service/issues/1102)) + +### Features + +* add "plan/create-admin-session" capability ([#1411](https://github.com/storacha/upload-service/issues/1411)) ([50eeeb5](https://github.com/storacha/upload-service/commit/50eeeb502335ba0413318b5047869a275901824b)) +* add `subscription/list` capability ([#1088](https://github.com/storacha/upload-service/issues/1088)) ([471d7e5](https://github.com/storacha/upload-service/commit/471d7e5db24e12a06c1c52ae76bf95ff9471bac8)) +* add blob protocol to upload-client ([#1425](https://github.com/storacha/upload-service/issues/1425)) ([49aef56](https://github.com/storacha/upload-service/commit/49aef564a726d34dbbedbd83f5366d9320180f99)) +* add CLI ([#39](https://github.com/storacha/upload-service/issues/39)) ([112720e](https://github.com/storacha/upload-service/commit/112720e098d24b49e4f142fe52c2a1d316e5353f)) +* coupon ([#1136](https://github.com/storacha/upload-service/issues/1136)) ([1b94f2d](https://github.com/storacha/upload-service/commit/1b94f2d3f6538d717d38b21dcb76657fd1f3e268)) +* expose OwnedSpace and SharedSpace from access-client ([#1244](https://github.com/storacha/upload-service/issues/1244)) ([8ec1b44](https://github.com/storacha/upload-service/commit/8ec1b446590399aa236904c1b6937b7be5d83054)) +* generate sharded DAG index on client and invoke w `index/add` ([#1451](https://github.com/storacha/upload-service/issues/1451)) ([a6d9026](https://github.com/storacha/upload-service/commit/a6d9026536e60c0ce93b613acc6e337f2a21aeb2)) +* Generate Space proofs on the fly, on `access/claim` ([#1555](https://github.com/storacha/upload-service/issues/1555)) ([9e2b1d4](https://github.com/storacha/upload-service/commit/9e2b1d4dc721d3e61cea008719d172909c984344)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) +* tweak readmes to get release-please to bump major version ([#1102](https://github.com/storacha/upload-service/issues/1102)) ([a411255](https://github.com/storacha/upload-service/commit/a4112551f5dbac00f4b5a0da8c81ea35783f3ef9)) +* two more interface tweaks ([#1287](https://github.com/storacha/upload-service/issues/1287)) ([bc3c364](https://github.com/storacha/upload-service/commit/bc3c36452454398ea8e0f574aed44b318561ad94)) +* upgrade ucanto/transport to 9.1.0 in all packages to get more verbose errors from HTTP transport on non-ok response ([#1312](https://github.com/storacha/upload-service/issues/1312)) ([d6978d7](https://github.com/storacha/upload-service/commit/d6978d7ab299be76987c6533d18e6857f6998fe6)) +* **upload-api:** integrate agent store for idempotence & invocation/receipt persistence ([#1444](https://github.com/storacha/upload-service/issues/1444)) ([c9bf33e](https://github.com/storacha/upload-service/commit/c9bf33e5512397a654db933a5e6b5db0c7c22da5)) +* w3up client login ([#1120](https://github.com/storacha/upload-service/issues/1120)) ([8279bf6](https://github.com/storacha/upload-service/commit/8279bf6371182709b46e83e5ac86d89ed1f292e8)) + + +### Fixes + +* access client should request blob namespace capabilities ([#1378](https://github.com/storacha/upload-service/issues/1378)) ([fc5bb4a](https://github.com/storacha/upload-service/commit/fc5bb4a83d50374e0e1a6006a8dbd655173ec498)) +* access-client package.json uses https instead of git for one-webcrypto dep to help with yarn compat ([#1157](https://github.com/storacha/upload-service/issues/1157)) ([e1d0798](https://github.com/storacha/upload-service/commit/e1d079811cceb0a68da371ba422ba6147e0fae4a)) +* don't error when we can't figure out a name for a space ([#1177](https://github.com/storacha/upload-service/issues/1177)) ([a31f667](https://github.com/storacha/upload-service/commit/a31f6671b52d37b8493ca1690ca737ddd311558b)) +* fix IndexedDB reset function ([#1199](https://github.com/storacha/upload-service/issues/1199)) ([48cf555](https://github.com/storacha/upload-service/commit/48cf55596162f68833f4cea49364a9dd5a845362)) +* floating promises and add no-floating-promises to eslint-config-w3up ([#1198](https://github.com/storacha/upload-service/issues/1198)) ([1b8c5aa](https://github.com/storacha/upload-service/commit/1b8c5aa86ec3d177bf77df4e2916699c1f522598)) +* issue where typedoc docs would only show full docs for w3up-client ([#1141](https://github.com/storacha/upload-service/issues/1141)) ([0b8d3f3](https://github.com/storacha/upload-service/commit/0b8d3f3b52918b1b4d3b76ea6fea3fb0c837cd73)) +* migrate repo ([#1389](https://github.com/storacha/upload-service/issues/1389)) ([475a287](https://github.com/storacha/upload-service/commit/475a28743ff9f7138b46dfe4227d3c80ed75a6a2)) +* package metadata ([#1161](https://github.com/storacha/upload-service/issues/1161)) ([b8a1cc2](https://github.com/storacha/upload-service/commit/b8a1cc2e125a91be582998bda295e1ae1caab087)) +* point `main` at files included in the package ([#1241](https://github.com/storacha/upload-service/issues/1241)) ([c0b306d](https://github.com/storacha/upload-service/commit/c0b306df75b21d0979e407f04f0a23f67d5248af)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* support storing ArrayBuffers in conf ([#1236](https://github.com/storacha/upload-service/issues/1236)) ([9b1aafb](https://github.com/storacha/upload-service/commit/9b1aafbcf241d268e4f365ed99005458dda1a05a)) +* sync space names from proofs ([#1193](https://github.com/storacha/upload-service/issues/1193)) ([f552036](https://github.com/storacha/upload-service/commit/f552036913cf7172e93e83e27fd4af6f7b6a4673)) +* upgrade @ucanto/validator with bugfix ([#1151](https://github.com/storacha/upload-service/issues/1151)) ([d4e961b](https://github.com/storacha/upload-service/commit/d4e961bab09e88245e7d9323146849271e78eb57)) +* upgrade type-fest in access ([#1263](https://github.com/storacha/upload-service/issues/1263)) ([47a4589](https://github.com/storacha/upload-service/commit/47a458964aaf1ebe07db4e29db60e558b9871fb6)) +* upgrade ucanto core ([#1127](https://github.com/storacha/upload-service/issues/1127)) ([5ce4d22](https://github.com/storacha/upload-service/commit/5ce4d2292d7e980da4a2ea0f1583f608a81157d2)) +* upgrade ucanto libs and format filecoin api ([#1359](https://github.com/storacha/upload-service/issues/1359)) ([87ca098](https://github.com/storacha/upload-service/commit/87ca098186fe204ff3409a2684719f1c54148c97)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) +* use an ArrayBuffer for delegation bits in AgentData ([#1219](https://github.com/storacha/upload-service/issues/1219)) ([bddf874](https://github.com/storacha/upload-service/commit/bddf87445755fa977768d636481eaee678a06e79)) +* use one-webcrypto from npm ([#1525](https://github.com/storacha/upload-service/issues/1525)) ([9345c54](https://github.com/storacha/upload-service/commit/9345c5415bc0b0d6ce8ccdbe92eb155b11835fd8)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* **main:** release access 17.0.0 ([#1103](https://github.com/storacha/upload-service/issues/1103)) ([5b34dfb](https://github.com/storacha/upload-service/commit/5b34dfbbee6766c70b47882ab3148628318bb100)) +* **main:** release access 17.1.0 ([#1122](https://github.com/storacha/upload-service/issues/1122)) ([3f302a3](https://github.com/storacha/upload-service/commit/3f302a39c0ebb075c35f7feecc31cd196ab66389)) +* **main:** release access 18.0.0 ([#1132](https://github.com/storacha/upload-service/issues/1132)) ([aa4ba63](https://github.com/storacha/upload-service/commit/aa4ba63179b17acf1d8d44fd1b092f895d25cb93)) +* **main:** release access 18.0.1 ([#1142](https://github.com/storacha/upload-service/issues/1142)) ([3d7f118](https://github.com/storacha/upload-service/commit/3d7f118699641edc6ab19784f6b3fa0c93588028)) +* **main:** release access 18.0.2 ([#1158](https://github.com/storacha/upload-service/issues/1158)) ([1dd371b](https://github.com/storacha/upload-service/commit/1dd371b3a1216cd73d9b4e71e393cb193796e72e)) +* **main:** release access 18.0.3 ([#1166](https://github.com/storacha/upload-service/issues/1166)) ([dfbc3f1](https://github.com/storacha/upload-service/commit/dfbc3f14a708daeac636413fa1316968d866db37)) +* **main:** release access 18.0.4 ([#1200](https://github.com/storacha/upload-service/issues/1200)) ([f51b066](https://github.com/storacha/upload-service/commit/f51b0664940193512ab34481858ad9beb9749ea3)) +* **main:** release access 18.0.5 ([#1203](https://github.com/storacha/upload-service/issues/1203)) ([89080ca](https://github.com/storacha/upload-service/commit/89080ca0329030610684bd85b0cfcf65a6850baf)) +* **main:** release access 18.0.6 ([#1233](https://github.com/storacha/upload-service/issues/1233)) ([ddb413f](https://github.com/storacha/upload-service/commit/ddb413f1255be8b39bc66ebea7c52fa56c3d1850)) +* **main:** release access 18.0.7 ([#1237](https://github.com/storacha/upload-service/issues/1237)) ([bb5235f](https://github.com/storacha/upload-service/commit/bb5235ff841430036152989442770c298f6f9d63)) +* **main:** release access 18.1.0 ([#1243](https://github.com/storacha/upload-service/issues/1243)) ([4991f70](https://github.com/storacha/upload-service/commit/4991f701e6eda6a6ce7434bbfa4b11282b675c3d)) +* **main:** release access 18.1.1 ([#1265](https://github.com/storacha/upload-service/issues/1265)) ([3244a26](https://github.com/storacha/upload-service/commit/3244a26ac10fb76858903f5271111d350cca05e8)) +* **main:** release access 18.2.0 ([#1288](https://github.com/storacha/upload-service/issues/1288)) ([787fca6](https://github.com/storacha/upload-service/commit/787fca6d1132f8e4a40706e47630285f49ca6a73)) +* **main:** release access 18.3.0 ([#1319](https://github.com/storacha/upload-service/issues/1319)) ([5701761](https://github.com/storacha/upload-service/commit/5701761e57b749726f1d4503393f567db9b6188d)) +* **main:** release access 18.3.1 ([#1381](https://github.com/storacha/upload-service/issues/1381)) ([086759d](https://github.com/storacha/upload-service/commit/086759dffebacf82af8dda4457e45f7033d3b3c8)) +* **main:** release access 18.3.2 ([#1396](https://github.com/storacha/upload-service/issues/1396)) ([bcc958f](https://github.com/storacha/upload-service/commit/bcc958f5a39507fc14d435095ec583e2ed03934e)) +* **main:** release access 18.4.0 ([#1446](https://github.com/storacha/upload-service/issues/1446)) ([af9f44e](https://github.com/storacha/upload-service/commit/af9f44eafcf80ad56464167afbcc0fdaa9a85b67)) +* **main:** release access 19.0.0 ([#1462](https://github.com/storacha/upload-service/issues/1462)) ([b16a0bf](https://github.com/storacha/upload-service/commit/b16a0bf05fba0ec66d2ef4bb80a3926169338ad2)) +* **main:** release access 20.0.0 ([#1473](https://github.com/storacha/upload-service/issues/1473)) ([be8247f](https://github.com/storacha/upload-service/commit/be8247f0ee047f9d61375230f39f103724114859)) +* **main:** release access 20.0.1 ([#1529](https://github.com/storacha/upload-service/issues/1529)) ([a82c4fb](https://github.com/storacha/upload-service/commit/a82c4fbd417f337d5ceb96d8dfb0ce7e884500ff)) +* **main:** release access 20.1.0 ([#1541](https://github.com/storacha/upload-service/issues/1541)) ([89836c0](https://github.com/storacha/upload-service/commit/89836c08ef10c1fd38e6b864e746be45c27514aa)) +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [20.1.0](https://github.com/storacha/w3up/compare/access-v20.0.1...access-v20.1.0) (2024-10-20) diff --git a/packages/access-client/package.json b/packages/access-client/package.json index d3602ef69..fb57b1620 100644 --- a/packages/access-client/package.json +++ b/packages/access-client/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/access", - "version": "20.1.0", - "description": "w3access client", - "homepage": "https://web3.storage", + "name": "@storacha/access", + "version": "1.0.2", + "description": "access client", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/access-client" }, "author": "Hugo Dias (hugodias.me)", @@ -99,25 +99,26 @@ ], "dependencies": { "@ipld/car": "^5.1.1", - "@ipld/dag-ucan": "^3.4.0", + "@ipld/dag-ucan": "^3.4.5", "@scure/bip39": "^1.2.1", + "@storacha/capabilities": "workspace:^", + "@storacha/did-mailto": "workspace:^", "@storacha/one-webcrypto": "^1.0.1", "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/principal": "^9.0.1", + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/principal": "^9.0.2", "@ucanto/transport": "^9.1.1", - "@ucanto/validator": "^9.0.2", - "@web3-storage/capabilities": "workspace:^", - "@web3-storage/did-mailto": "workspace:^", + "@ucanto/validator": "^9.0.3", "bigint-mod-arith": "^3.1.2", "conf": "11.0.2", - "multiformats": "^12.1.2", + "multiformats": "^13.3.1", "p-defer": "^4.0.0", "type-fest": "^4.9.0", - "uint8arrays": "^4.0.6" + "uint8arrays": "^5.1.0" }, "devDependencies": { + "@storacha/eslint-config": "workspace:^", "@types/assert": "^1.5.6", "@types/inquirer": "^9.0.4", "@types/mocha": "^10.0.1", @@ -125,8 +126,7 @@ "@types/sinon": "^10.0.19", "@types/varint": "^6.0.1", "@types/ws": "^8.5.4", - "@ucanto/server": "^10.0.0", - "@web3-storage/eslint-config-w3up": "workspace:^", + "@ucanto/server": "^10.1.0", "assert": "^2.0.0", "mocha": "^10.2.0", "playwright-test": "^12.3.4", @@ -136,7 +136,7 @@ }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -158,7 +158,7 @@ "ignores": [ "@types/*", "assert", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] } } diff --git a/packages/access-client/readme.md b/packages/access-client/readme.md index c5781b62a..156508302 100644 --- a/packages/access-client/readme.md +++ b/packages/access-client/readme.md @@ -1,9 +1,9 @@ -


web3.storage

-

The access client for https://web3.storage

+


storacha.network

+

The access client for https://storacha.network

## About -The `@web3-storage/access` package provides an API for creating and managing "agents," which are software entities that control private signing keys and can invoke capabilities on behalf of a user (or another agent). +The `@storacha/access` package provides an API for creating and managing "agents," which are software entities that control private signing keys and can invoke capabilities on behalf of a user (or another agent). Agents are used to invoke capabilities provided by the w3up service layer, using the [ucanto](https://github.com/storacha/ucanto) RPC framework. Agents are created locally on an end-user's device, and users are encouraged to create new agents for each device (or browser) that they want to use, rather than sharing agent keys between devices. @@ -11,14 +11,14 @@ An Agent can create "spaces," which are namespaces for content stored on the w3u Although agents (and spaces) are created locally by generating keypairs, the w3up services will only act upon spaces that have been registered with the w3up access service. By default, a newly-created agent will be configured to use the production access service for remote operations, including registration. -Please note that the `@web3-storage/access` package is a fairly "low level" component of the w3up JavaScript stack, and most users will be better served by [`@web3-storage/w3up-client`](https://github.com/storacha/w3up-client), which combines this package with a client for the upload and storage service and presents a simpler API. +Please note that the `@storacha/access` package is a fairly "low level" component of the w3up JavaScript stack, and most users will be better served by [`@storacha/client`](https://github.com/storacha/upload-service/tree/main/packages/w3up-client), which combines this package with a client for the upload and storage service and presents a simpler API. ## Install Install the package: ```bash -npm install @web3-storage/access +npm install @storacha/access ``` ## Usage @@ -34,8 +34,8 @@ If you're running in a web browser, use [`StoreIndexedDB`](https://web3-storage. Agents in a browser use RSA keys, which can be generated using the async `generate` function from `@ucanto/principal/rsa`. ```js -import { Agent } from '@web3-storage/access/agent' -import { StoreIndexedDB } from '@web3-storage/access/stores/store-indexeddb' +import { Agent } from '@storacha/access/agent' +import { StoreIndexedDB } from '@storacha/access/stores/store-indexeddb' import { generate } from '@ucanto/principal/rsa' async function createAgent() { @@ -63,8 +63,8 @@ On node.js, use [`StoreConf`](https://web3-storage.github.io/w3up/classes/_web3_ Agents on node should use Ed25519 keys: ```js -import { Agent } from '@web3-storage/access/agent' -import { StoreConf } from '@web3-storage/access/stores/store-conf' +import { Agent } from '@storacha/access/agent' +import { StoreConf } from '@storacha/access/stores/store-conf' import { generate } from '@ucanto/principal/ed25519' async function createAgent() { @@ -164,9 +164,9 @@ The [`importSpaceFromDelegation` method](https://web3-storage.github.io/w3up/cla ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/license.md) +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/license.md) diff --git a/packages/access-client/src/access.js b/packages/access-client/src/access.js index 79cb76c9b..b08a2d894 100644 --- a/packages/access-client/src/access.js +++ b/packages/access-client/src/access.js @@ -1,4 +1,4 @@ -import * as Access from '@web3-storage/capabilities/access' +import * as Access from '@storacha/capabilities/access' import * as API from './types.js' import { Failure, fail, DID } from '@ucanto/core' import { Agent, importAuthorization } from './agent.js' diff --git a/packages/access-client/src/agent-data.js b/packages/access-client/src/agent-data.js index 3b0cbfed0..dd8e341bb 100644 --- a/packages/access-client/src/agent-data.js +++ b/packages/access-client/src/agent-data.js @@ -3,7 +3,7 @@ import { Signer as EdSigner } from '@ucanto/principal/ed25519' import { importDAG } from '@ucanto/core/delegation' import * as Ucanto from '@ucanto/interface' import { CID } from 'multiformats' -import { UCAN } from '@web3-storage/capabilities' +import { UCAN } from '@storacha/capabilities' import { isExpired } from './delegations.js' import { uint8ArrayToArrayBuffer } from './utils/buffers.js' diff --git a/packages/access-client/src/agent-use-cases.js b/packages/access-client/src/agent-use-cases.js index fe8cc4f75..dcb5d8d74 100644 --- a/packages/access-client/src/agent-use-cases.js +++ b/packages/access-client/src/agent-use-cases.js @@ -1,11 +1,11 @@ import { addSpacesFromDelegations, Agent as AccessAgent } from './agent.js' -import * as Access from '@web3-storage/capabilities/access' +import * as Access from '@storacha/capabilities/access' import { bytesToDelegations } from './encoding.js' -import { Provider, Plan } from '@web3-storage/capabilities' -import * as w3caps from '@web3-storage/capabilities' +import { Provider, Plan } from '@storacha/capabilities' +import * as w3caps from '@storacha/capabilities' import { Schema, delegate } from '@ucanto/core' import { AgentData, isSessionProof } from './agent-data.js' -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' import * as API from './types.js' const DIDWeb = Schema.DID.match({ method: 'web' }) @@ -73,7 +73,7 @@ export async function claimAccess( * @param {AccessAgent} opts.access * @param {API.SpaceDID} opts.space * @param {API.Principal} opts.account - * @param {API.ProviderDID} opts.provider - e.g. 'did:web:staging.web3.storage' + * @param {API.ProviderDID} opts.provider - e.g. 'did:web:staging.storacha.network' */ export async function addProvider({ access, space, account, provider }) { const result = await access.invokeAndExecute(Provider.add, { @@ -255,7 +255,7 @@ export async function addProviderAndDelegateToAccount( } if (spaceMeta) { - throw new Error('Space already registered with web3.storage.') + throw new Error('Space already registered with storacha.network.') } const account = { did: () => DidMailto.fromEmail(DidMailto.email(email)) } await addProvider({ access, space, account, provider }) diff --git a/packages/access-client/src/agent.js b/packages/access-client/src/agent.js index bde24a61c..5fc067ef9 100644 --- a/packages/access-client/src/agent.js +++ b/packages/access-client/src/agent.js @@ -2,8 +2,8 @@ import * as Client from '@ucanto/client' import * as CAR from '@ucanto/transport/car' import * as HTTP from '@ucanto/transport/http' import * as ucanto from '@ucanto/core' -import * as Capabilities from '@web3-storage/capabilities/space' -import { attest } from '@web3-storage/capabilities/ucan' +import * as Capabilities from '@storacha/capabilities/space' +import { attest } from '@storacha/capabilities/ucan' import * as Access from './access.js' import * as Space from './space.js' @@ -17,7 +17,7 @@ import { } from '@ucanto/core' import { isExpired, isTooEarly, canDelegateCapability } from './delegations.js' import { AgentData, getSessionProofs } from './agent-data.js' -import { UCAN } from '@web3-storage/capabilities' +import { UCAN } from '@storacha/capabilities' import * as API from './types.js' @@ -26,8 +26,8 @@ export * from './delegations.js' export { AgentData, Access, Space, Delegation, Schema } export * from './agent-use-cases.js' -const HOST = 'https://up.web3.storage' -const PRINCIPAL = DID.parse('did:web:web3.storage') +const HOST = 'https://up.storacha.network' +const PRINCIPAL = DID.parse('did:web:storacha.network') /** * Keeps track of AgentData for all Agents constructed. @@ -50,7 +50,7 @@ const agentToData = new WeakMap() * Usage: * * ```js - * import { connection } from '@web3-storage/access/agent' + * import { connection } from '@storacha/access/agent' * ``` * * @template {API.DID} T - DID method @@ -82,7 +82,7 @@ export function connection(options = {}) { * Usage: * * ```js - * import { Agent } from '@web3-storage/access/agent' + * import { Agent } from '@storacha/access/agent' * ``` * * @template {Record} [S=Service] @@ -239,7 +239,7 @@ export class Agent { } } const receipt = await this.invokeAndExecute(UCAN.revoke, { - // per https://github.com/storacha/w3up/blob/main/packages/capabilities/src/ucan.js#L38C6-L38C6 the resource here should be + // per https://github.com/storacha/upload-service/blob/main/packages/capabilities/src/ucan.js#L38C6-L38C6 the resource here should be // the current issuer - using the space DID here works for simple cases but falls apart when a delegee tries to revoke a delegation // they have re-delegated, since they don't have "ucan/revoke" capabilities on the space with: this.issuer.did(), @@ -505,7 +505,7 @@ export class Agent { * const i1 = await agent.invoke(Space.info, {}) * const i2 = await agent.invoke(Space.recover, { * nb: { - * identity: 'mailto:hello@web3.storage', + * identity: 'mailto:hello@storacha.network', * }, * }) * @@ -577,7 +577,7 @@ export class Agent { // @ts-ignore capability: cap.create({ with: space, - nb: options.nb, + nb: 'nb' in options ? options.nb : undefined, }), issuer: this.issuer, proofs: [...proofs], diff --git a/packages/access-client/src/crypto/encoding.js b/packages/access-client/src/crypto/encoding.js index 9159754ff..eb04b00df 100644 --- a/packages/access-client/src/crypto/encoding.js +++ b/packages/access-client/src/crypto/encoding.js @@ -91,6 +91,6 @@ export function decompressP256(comp) { yPadded.set(y, offset) // concat coords & prepend P-256 prefix - const publicKey = uint8arrays.concat([[0x04], x, yPadded]) + const publicKey = uint8arrays.concat([new Uint8Array([0x04]), x, yPadded]) return publicKey } diff --git a/packages/access-client/src/delegations.js b/packages/access-client/src/delegations.js index 7cda291f6..ccf6c42d1 100644 --- a/packages/access-client/src/delegations.js +++ b/packages/access-client/src/delegations.js @@ -1,6 +1,6 @@ import * as ucanto from '@ucanto/core' import * as API from './types.js' -import { canDelegateAbility } from '@web3-storage/capabilities/utils' +import { canDelegateAbility } from '@storacha/capabilities/utils' /** * diff --git a/packages/access-client/src/drivers/conf.js b/packages/access-client/src/drivers/conf.js index ddf27bc10..af3979e9e 100644 --- a/packages/access-client/src/drivers/conf.js +++ b/packages/access-client/src/drivers/conf.js @@ -12,7 +12,7 @@ import * as JSON from '../utils/json.js' * Usage: * * ```js - * import { ConfDriver } from '@web3-storage/access/drivers/conf' + * import { ConfDriver } from '@storacha/access/drivers/conf' * ``` * * @template {Record} T diff --git a/packages/access-client/src/drivers/indexeddb.js b/packages/access-client/src/drivers/indexeddb.js index 6991d4afe..32eea8f0c 100644 --- a/packages/access-client/src/drivers/indexeddb.js +++ b/packages/access-client/src/drivers/indexeddb.js @@ -14,7 +14,7 @@ const DATA_ID = 1 * Usage: * * ```js - * import { IndexedDBDriver } from '@web3-storage/access/drivers/indexeddb' + * import { IndexedDBDriver } from '@storacha/access/drivers/indexeddb' * ``` * * @template T diff --git a/packages/access-client/src/drivers/memory.js b/packages/access-client/src/drivers/memory.js index 9b89f185c..4a7e795d9 100644 --- a/packages/access-client/src/drivers/memory.js +++ b/packages/access-client/src/drivers/memory.js @@ -9,7 +9,7 @@ * Usage: * * ```js - * import { MemoryDriver } from '@web3-storage/access/drivers/memory' + * import { MemoryDriver } from '@storacha/access/drivers/memory' * ``` * * @template {Record} T diff --git a/packages/access-client/src/encoding.js b/packages/access-client/src/encoding.js index 479412588..1a714c43d 100644 --- a/packages/access-client/src/encoding.js +++ b/packages/access-client/src/encoding.js @@ -3,11 +3,11 @@ * * It is recommended that you import directly with: * ```js - * import * as Encoding from '@web3-storage/access/encoding' + * import * as Encoding from '@storacha/access/encoding' * * // or * - * import { encodeDelegations } from '@web3-storage/access/encoding' + * import { encodeDelegations } from '@storacha/access/encoding' * ``` * * @module diff --git a/packages/access-client/src/provider.js b/packages/access-client/src/provider.js index 42717175f..9bf41c970 100644 --- a/packages/access-client/src/provider.js +++ b/packages/access-client/src/provider.js @@ -1,5 +1,5 @@ import * as API from './types.js' -import * as Provider from '@web3-storage/capabilities/provider' +import * as Provider from '@storacha/capabilities/provider' export const { Provider: ProviderDID, AccountDID } = Provider diff --git a/packages/access-client/src/stores/store-conf.js b/packages/access-client/src/stores/store-conf.js index b0d91b218..4f60ae929 100644 --- a/packages/access-client/src/stores/store-conf.js +++ b/packages/access-client/src/stores/store-conf.js @@ -6,7 +6,7 @@ import { ConfDriver } from '../drivers/conf.js' * Usage: * * ```js - * import { StoreConf } from '@web3-storage/access/stores/store-conf' + * import { StoreConf } from '@storacha/access/stores/store-conf' * ``` * * @extends {ConfDriver} diff --git a/packages/access-client/src/stores/store-indexeddb.js b/packages/access-client/src/stores/store-indexeddb.js index 68071efc1..51278a646 100644 --- a/packages/access-client/src/stores/store-indexeddb.js +++ b/packages/access-client/src/stores/store-indexeddb.js @@ -6,7 +6,7 @@ import { IndexedDBDriver } from '../drivers/indexeddb.js' * Usage: * * ```js - * import { StoreIndexedDB } from '@web3-storage/access/stores/store-indexeddb' + * import { StoreIndexedDB } from '@storacha/access/stores/store-indexeddb' * ``` * * @extends {IndexedDBDriver} diff --git a/packages/access-client/src/stores/store-memory.js b/packages/access-client/src/stores/store-memory.js index e9b40df55..1a1dc2605 100644 --- a/packages/access-client/src/stores/store-memory.js +++ b/packages/access-client/src/stores/store-memory.js @@ -6,7 +6,7 @@ import { MemoryDriver } from '../drivers/memory.js' * Usage: * * ```js - * import { StoreMemory } from '@web3-storage/access/stores/store-memory' + * import { StoreMemory } from '@storacha/access/stores/store-memory' * ``` * * @extends {MemoryDriver} diff --git a/packages/access-client/src/types.ts b/packages/access-client/src/types.ts index ee1011772..5adc6c2a1 100644 --- a/packages/access-client/src/types.ts +++ b/packages/access-client/src/types.ts @@ -64,16 +64,16 @@ import type { PlanCreateAdminSession, PlanCreateAdminSessionSuccess, PlanCreateAdminSessionFailure, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' import type { SetRequired } from 'type-fest' import { Driver } from './drivers/types.js' import { SpaceUnknown } from './errors.js' // export other types export * from '@ucanto/interface' -export * from '@web3-storage/capabilities/types' +export * from '@storacha/capabilities/types' export * from './errors.js' -export * from '@web3-storage/did-mailto' +export * from '@storacha/did-mailto' export type { Agent } from './agent.js' export type { OwnedSpace, SharedSpace } from './space.js' @@ -249,7 +249,7 @@ export type InvokeOptions< Match<{ can: A; with: R & Resource; nb: Caveats }, UnknownMatch> > > = UCANBasicOptions & - InferNb['nb']> & { + Omit, 'can' | 'with'> & { /** * Resource for the capability, normally a Space DID * Defaults to the current selected Space diff --git a/packages/access-client/test/agent-data.test.js b/packages/access-client/test/agent-data.test.js index fb8b4f276..d955e37f8 100644 --- a/packages/access-client/test/agent-data.test.js +++ b/packages/access-client/test/agent-data.test.js @@ -1,9 +1,9 @@ import assert from 'assert' import { AgentData, getSessionProofs } from '../src/agent-data.js' import * as ed25519 from '@ucanto/principal/ed25519' -import { UCAN } from '@web3-storage/capabilities' +import { UCAN } from '@storacha/capabilities' import { Absentee } from '@ucanto/principal' -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' import * as ucanto from '@ucanto/core' describe('AgentData', () => { @@ -35,9 +35,9 @@ describe('AgentData', () => { ) const agentData = await AgentData.create() const serviceA = await ed25519.Signer.generate() - const serviceAWeb = serviceA.withDID('did:web:a.up.web3.storage') + const serviceAWeb = serviceA.withDID('did:web:a.up.storacha.network') const serviceB = await ed25519.Signer.generate() - const serviceBWeb = serviceB.withDID('did:web:b.up.web3.storage') + const serviceBWeb = serviceB.withDID('did:web:b.up.storacha.network') const services = [serviceAWeb, serviceBWeb] // note: this delegation has same CID in all loops since nothing service-specific is in the delegation diff --git a/packages/access-client/test/agent-use-cases.test.js b/packages/access-client/test/agent-use-cases.test.js index 9783c9b51..94a585d19 100644 --- a/packages/access-client/test/agent-use-cases.test.js +++ b/packages/access-client/test/agent-use-cases.test.js @@ -2,11 +2,11 @@ import assert from 'assert' import sinon from 'sinon' import * as Server from '@ucanto/server' import * as Ucanto from '@ucanto/interface' -import * as Access from '@web3-storage/capabilities/access' -import * as Ucan from '@web3-storage/capabilities/ucan' -import * as Space from '@web3-storage/capabilities/space' -import * as Plan from '@web3-storage/capabilities/plan' -import { createAuthorization } from '@web3-storage/capabilities/test/helpers/utils' +import * as Access from '@storacha/capabilities/access' +import * as Ucan from '@storacha/capabilities/ucan' +import * as Space from '@storacha/capabilities/space' +import * as Plan from '@storacha/capabilities/plan' +import { createAuthorization } from '@storacha/capabilities/test/helpers/utils' import { Agent, connection } from '../src/agent.js' import { delegationsIncludeSessionProof, @@ -197,7 +197,7 @@ describe('authorizeWaitAndClaim', async function () { describe('getAccountPlan', async function () { const accountWithAPlan = 'did:mailto:example.com:i-have-a-plan' const accountWithoutAPlan = 'did:mailto:example.com:i-have-no-plan' - const product = 'did:web:test.web3.storage' + const product = 'did:web:test.upload.storacha.network' /** @type {Record} */ const plans = { [accountWithAPlan]: { diff --git a/packages/access-client/test/agent.test.js b/packages/access-client/test/agent.test.js index 2849ccb85..478f80554 100644 --- a/packages/access-client/test/agent.test.js +++ b/packages/access-client/test/agent.test.js @@ -3,13 +3,13 @@ import * as ucanto from '@ucanto/core' import { URI } from '@ucanto/validator' import { Delegation, provide } from '@ucanto/server' import { Agent, Access, AgentData, connection } from '../src/agent.js' -import * as Space from '@web3-storage/capabilities/space' +import * as Space from '@storacha/capabilities/space' import { createServer } from './helpers/utils.js' import * as fixtures from './helpers/fixtures.js' import * as ed25519 from '@ucanto/principal/ed25519' -import { UCAN, Provider } from '@web3-storage/capabilities' +import { UCAN, Provider } from '@storacha/capabilities' import { Absentee } from '@ucanto/principal' -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' import * as API from '../src/types.js' describe('Agent', function () { @@ -415,9 +415,9 @@ describe('Agent', function () { `test-${Math.random().toString().slice(2)}@dag.house` ) const serviceA = await ed25519.Signer.generate() - const serviceAWeb = serviceA.withDID('did:web:a.up.web3.storage') + const serviceAWeb = serviceA.withDID('did:web:a.up.storacha.network') const serviceB = await ed25519.Signer.generate() - const serviceBWeb = serviceB.withDID('did:web:b.up.web3.storage') + const serviceBWeb = serviceB.withDID('did:web:b.up.storacha.network') const server = createServer() const agentData = await AgentData.create() @@ -469,9 +469,9 @@ describe('Agent', function () { `test-${Math.random().toString().slice(2)}@dag.house` ) const serviceA = await ed25519.Signer.generate() - const serviceAWeb = serviceA.withDID('did:web:a.up.web3.storage') + const serviceAWeb = serviceA.withDID('did:web:a.up.storacha.network') const serviceB = await ed25519.Signer.generate() - const serviceBWeb = serviceB.withDID('did:web:b.up.web3.storage') + const serviceBWeb = serviceB.withDID('did:web:b.up.storacha.network') const server = createServer() const agentData = await AgentData.create() diff --git a/packages/access-client/test/helpers/utils.js b/packages/access-client/test/helpers/utils.js index f377a0d49..c515e6908 100644 --- a/packages/access-client/test/helpers/utils.js +++ b/packages/access-client/test/helpers/utils.js @@ -2,7 +2,7 @@ import * as Ucanto from '@ucanto/interface' import { parseLink } from '@ucanto/core' import * as Server from '@ucanto/server' -import * as Space from '@web3-storage/capabilities/space' +import * as Space from '@storacha/capabilities/space' import * as CAR from '@ucanto/transport/car' import * as CBOR from '@ucanto/core/cbor' import { service } from './fixtures.js' diff --git a/packages/access-client/test/stores/store-conf.node.test.js b/packages/access-client/test/stores/store-conf.node.test.js index 24a63821c..09725bef8 100644 --- a/packages/access-client/test/stores/store-conf.node.test.js +++ b/packages/access-client/test/stores/store-conf.node.test.js @@ -1,5 +1,5 @@ import assert from 'assert' -import { top } from '@web3-storage/capabilities/top' +import { top } from '@storacha/capabilities/top' import { Signer as EdSigner } from '@ucanto/principal/ed25519' import * as RSASigner from '@ucanto/principal/rsa' import { AgentData } from '../../src/agent-data.js' diff --git a/packages/access-client/test/stores/store-indexeddb.browser.test.js b/packages/access-client/test/stores/store-indexeddb.browser.test.js index 06a4bb132..86f9cc105 100644 --- a/packages/access-client/test/stores/store-indexeddb.browser.test.js +++ b/packages/access-client/test/stores/store-indexeddb.browser.test.js @@ -1,5 +1,5 @@ import assert from 'assert' -import { top } from '@web3-storage/capabilities/top' +import { top } from '@storacha/capabilities/top' import { Signer as EdSigner } from '@ucanto/principal/ed25519' import * as RSASigner from '@ucanto/principal/rsa' import { AgentData } from '../../src/agent-data.js' diff --git a/packages/blob-index/CHANGELOG.md b/packages/blob-index/CHANGELOG.md index 9363b9de6..8da98cc36 100644 --- a/packages/blob-index/CHANGELOG.md +++ b/packages/blob-index/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## [1.0.1](https://github.com/storacha/upload-service/compare/blob-index-v1.0.0...blob-index-v1.0.1) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## 1.0.0 (2024-12-19) + + +### Features + +* move blob index logic from upload-api to blob-index lib ([#1434](https://github.com/storacha/upload-service/issues/1434)) ([797f628](https://github.com/storacha/upload-service/commit/797f6285c1b000af9eaf0240f85deca6a0b83e06)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) + + +### Fixes + +* check for blob/accept receipts before blob/add is concluded ([#1459](https://github.com/storacha/upload-service/issues/1459)) ([462518c](https://github.com/storacha/upload-service/commit/462518ca832515c65cc674e8aef3c28f2228797d)) +* missing blob-index deps ([#1467](https://github.com/storacha/upload-service/issues/1467)) ([deb8cc9](https://github.com/storacha/upload-service/commit/deb8cc97b6e21db9e863a6ae2b457cf13af5454b)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* trigger release ([0bf74f4](https://github.com/storacha/upload-service/commit/0bf74f44183e38d298308ccd469589c07cd760b0)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) +* use one-webcrypto from npm ([#1525](https://github.com/storacha/upload-service/issues/1525)) ([9345c54](https://github.com/storacha/upload-service/commit/9345c5415bc0b0d6ce8ccdbe92eb155b11835fd8)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* **main:** release blob-index 1.0.0 ([#1449](https://github.com/storacha/upload-service/issues/1449)) ([094442b](https://github.com/storacha/upload-service/commit/094442b0d5c9d837a0575b79a4d07441a4de2229)) +* **main:** release blob-index 1.0.1 ([#1452](https://github.com/storacha/upload-service/issues/1452)) ([3d9809f](https://github.com/storacha/upload-service/commit/3d9809f5850e605cba4bf4d13783bf42941b5538)) +* **main:** release blob-index 1.0.2 ([#1468](https://github.com/storacha/upload-service/issues/1468)) ([fb6e5a1](https://github.com/storacha/upload-service/commit/fb6e5a13d3f5be11cd86320d75160c236fbc9d16)) +* **main:** release blob-index 1.0.3 ([#1489](https://github.com/storacha/upload-service/issues/1489)) ([fc71d31](https://github.com/storacha/upload-service/commit/fc71d313768ff0e94ee84d91ed205dc13894ff2e)) +* **main:** release blob-index 1.0.4 ([#1526](https://github.com/storacha/upload-service/issues/1526)) ([a79ea18](https://github.com/storacha/upload-service/commit/a79ea184f6e24668638e85eb344134dffbeddc9e)) +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [1.0.4](https://github.com/storacha-network/w3up/compare/blob-index-v1.0.3...blob-index-v1.0.4) (2024-07-29) diff --git a/packages/blob-index/README.md b/packages/blob-index/README.md index e95bc39f6..faa644e4c 100644 --- a/packages/blob-index/README.md +++ b/packages/blob-index/README.md @@ -1,11 +1,11 @@ -# `@web3-storage/blob-index` +# `@storacha/blob-index` An index for slices that may be sharded across multiple blobs. ## Install ```sh -npm install @web3-storage/blob-index +npm install @storacha/blob-index ``` ## Usage @@ -13,7 +13,7 @@ npm install @web3-storage/blob-index Create: ```js -import { ShardedDAGIndex } from '@web3-storage/blob-index' +import { ShardedDAGIndex } from '@storacha/blob-index' // Create a brand new index const index = ShardedDAGIndex.create(rootCID) @@ -31,7 +31,7 @@ console.log(result.ok) // a Uint8Array Read: ```js -import { ShardedDAGIndex } from '@web3-storage/blob-index' +import { ShardedDAGIndex } from '@storacha/blob-index' import { base58btc } from 'multiformats/bases/base58' const index = ShardedDAGIndex.extract(car) @@ -55,8 +55,8 @@ for (const [shard, slices] of index.shards.entries()) { ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/license.md) +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/license.md) diff --git a/packages/blob-index/package.json b/packages/blob-index/package.json index 2bfe792ff..97d651f2d 100644 --- a/packages/blob-index/package.json +++ b/packages/blob-index/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/blob-index", + "name": "@storacha/blob-index", "description": "An index for slices that may be sharded across multiple blobs.", - "version": "1.0.4", - "homepage": "https://web3.storage", + "version": "1.0.1", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/blob-index" }, "license": "Apache-2.0 OR MIT", @@ -41,24 +41,24 @@ }, "dependencies": { "@ipld/dag-cbor": "^9.0.6", + "@storacha/capabilities": "workspace:^", "@storacha/one-webcrypto": "^1.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@web3-storage/capabilities": "workspace:^", + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", "carstream": "^2.1.0", "multiformats": "^13.0.1", "uint8arrays": "^5.0.3" }, "devDependencies": { + "@storacha/eslint-config": "workspace:^", "@ucanto/transport": "^9.1.1", - "@web3-storage/eslint-config-w3up": "workspace:^", "c8": "^7.14.0", "entail": "^2.1.2", "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" diff --git a/packages/blob-index/src/api.ts b/packages/blob-index/src/api.ts index 8f94529bd..62b8f569c 100644 --- a/packages/blob-index/src/api.ts +++ b/packages/blob-index/src/api.ts @@ -2,7 +2,7 @@ import { Result, Failure } from '@ucanto/interface' import { MultihashDigest, Link, UnknownLink } from 'multiformats' export type { IPLDBlock } from '@ucanto/interface' -export type { UnknownFormat } from '@web3-storage/capabilities/types' +export type { UnknownFormat } from '@storacha/capabilities/types' export type { Result, MultihashDigest, Link, UnknownLink } export type ShardDigest = MultihashDigest diff --git a/packages/blob-index/src/util.js b/packages/blob-index/src/util.js index b0a2bd45c..0b88e987f 100644 --- a/packages/blob-index/src/util.js +++ b/packages/blob-index/src/util.js @@ -37,7 +37,7 @@ export const fromShardArchives = async (content, shards) => { * Indexes a sharded DAG * * @param {import('multiformats').Link} root - * @param {import('@web3-storage/capabilities/types').CARLink[]} shards + * @param {import('@storacha/capabilities/types').CARLink[]} shards * @param {Array>} shardIndexes */ export async function indexShardedDAG(root, shards, shardIndexes) { diff --git a/packages/capabilities/CHANGELOG.md b/packages/capabilities/CHANGELOG.md index 48cd60d4f..be4847bbc 100644 --- a/packages/capabilities/CHANGELOG.md +++ b/packages/capabilities/CHANGELOG.md @@ -1,5 +1,186 @@ # Changelog +## [1.2.1](https://github.com/storacha/upload-service/compare/capabilities-v1.2.0...capabilities-v1.2.1) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.2.0](https://github.com/storacha/upload-service/compare/capabilities-v1.1.2...capabilities-v1.2.0) (2024-12-19) + + +### Features + +* content serve authorization ([#1590](https://github.com/storacha/upload-service/issues/1590)) + set default gateway ([#99](https://github.com/storacha/upload-service/issues/99)) ([6cbb202](https://github.com/storacha/upload-service/commit/6cbb2027c829189937363b374e258bb1a2b07722)) + + +### Other Changes + +* **capabilities:** top level filecoin cap ([#105](https://github.com/storacha/upload-service/issues/105)) ([671a411](https://github.com/storacha/upload-service/commit/671a411c94f18eb6498a1751eebed7b4d4ea0c35)) +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## [1.1.2](https://github.com/storacha/upload-service/compare/capabilities-v1.1.1...capabilities-v1.1.2) (2024-12-12) + + +### Fixes + +* **egress/record:** Remove unnecessary multiplication for ts conversion ([#98](https://github.com/storacha/upload-service/issues/98)) ([79ac1ab](https://github.com/storacha/upload-service/commit/79ac1ab7690d10b672c3dfb0ae4ddd9cc420ee2f)) +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([98ab50c](https://github.com/storacha/upload-service/commit/98ab50cf0a5c7985a567e9507b04d948e425d623)) +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([#97](https://github.com/storacha/upload-service/issues/97)) ([df8b9a2](https://github.com/storacha/upload-service/commit/df8b9a2dd88871d33bd836aea431d7dbc2bc590c)) +* **egressRecord:** Remove unnecessary multiplication for ts conversion ([#1588](https://github.com/storacha/upload-service/issues/1588)) ([1870202](https://github.com/storacha/upload-service/commit/1870202f8b2551c4a30488f84530567572382fb0)) + +## [1.1.1](https://github.com/storacha/upload-service/compare/capabilities-v1.1.0...capabilities-v1.1.1) (2024-11-12) + + +### Other Changes + +* **main:** release capabilities 1.0.1 ([#42](https://github.com/storacha/upload-service/issues/42)) ([3f3452a](https://github.com/storacha/upload-service/commit/3f3452a5eff8d4c98ddbef05c9f6fafa0fb9434c)) + +## [1.1.0](https://github.com/storacha/upload-service/compare/capabilities-v1.0.0...capabilities-v1.1.0) (2024-11-12) + + +### Features + +* add CLI ([#39](https://github.com/storacha/upload-service/issues/39)) ([112720e](https://github.com/storacha/upload-service/commit/112720e098d24b49e4f142fe52c2a1d316e5353f)) + + +### Fixes + +* encode space DID as bytes in blob caveats ([#41](https://github.com/storacha/upload-service/issues/41)) ([6eba88d](https://github.com/storacha/upload-service/commit/6eba88d004492ea2eff19db88753d827ba267133)) + +## 1.0.0 (2024-11-05) + + +### Fixes + +* bootstrap sha ([cdf6737](https://github.com/storacha/upload-service/commit/cdf67371ee9df3a60f7fea90c310179b20ee2b0b)) + + +### Other Changes + +* **main:** release capabilities 1.0.0 ([#16](https://github.com/storacha/upload-service/issues/16)) ([1c0902d](https://github.com/storacha/upload-service/commit/1c0902d168df26e2d850f20563dd825af57d5490)) + +## 1.0.0 (2024-11-05) + + +### ⚠ BREAKING CHANGES + +* add `index/add` handler ([#1421](https://github.com/storacha/upload-service/issues/1421)) +* restrict store API to CARs ([#1415](https://github.com/storacha/upload-service/issues/1415)) +* **capabilities:** `BlobMultihash` type in `@web3-storage/capabilities` renamed to `Multihash`. +* allocations storage interface now requires remove to be implemented +* return allocated bytes in `store/add` receipt ([#1213](https://github.com/storacha/upload-service/issues/1213)) +* coupon ([#1136](https://github.com/storacha/upload-service/issues/1136)) +* see latest specs https://github.com/web3-storage/specs/blob/cbdb706f18567900c5c24d7fb16ccbaf93d0d023/w3-filecoin.md +* filecoin client to use new capabilities +* filecoin capabilities + +### refactor + +* filecoin api services events and tests ([#974](https://github.com/storacha/upload-service/issues/974)) ([953537b](https://github.com/storacha/upload-service/commit/953537bcb98d94b9e9655797a7f9026643ab949f)) +* filecoin capabilities ([c0b97bf](https://github.com/storacha/upload-service/commit/c0b97bf42d87b49d7de11119f9eb6166ab8d97d0)) +* filecoin client to use new capabilities ([b0d9c3f](https://github.com/storacha/upload-service/commit/b0d9c3f258d37701487ef02f70a93e2dd1a18775)) + + +### Features + +* add "plan/create-admin-session" capability ([#1411](https://github.com/storacha/upload-service/issues/1411)) ([50eeeb5](https://github.com/storacha/upload-service/commit/50eeeb502335ba0413318b5047869a275901824b)) +* add `index/add` handler ([#1421](https://github.com/storacha/upload-service/issues/1421)) ([cbe9524](https://github.com/storacha/upload-service/commit/cbe952451b719fe7ae2f7480d26865eca80aba55)) +* add `initialize` method to `PlansStorage` ([#1278](https://github.com/storacha/upload-service/issues/1278)) ([6792126](https://github.com/storacha/upload-service/commit/6792126d63a1e983713c3886eeba64038cb7cf34)) +* add `store/get` and `upload/get` capabilities ([#942](https://github.com/storacha/upload-service/issues/942)) ([40c79eb](https://github.com/storacha/upload-service/commit/40c79eb8f246775b9e1828240f271fa75ef696be)) +* add `subscription/list` capability ([#1088](https://github.com/storacha/upload-service/issues/1088)) ([471d7e5](https://github.com/storacha/upload-service/commit/471d7e5db24e12a06c1c52ae76bf95ff9471bac8)) +* add a function to verify and return Abilities. ([#1252](https://github.com/storacha/upload-service/issues/1252)) ([2f026a2](https://github.com/storacha/upload-service/commit/2f026a2483a4f323c4e2c6a8a8cb10afd92e21c4)) +* add blob list and remove ([#1385](https://github.com/storacha/upload-service/issues/1385)) ([2f69946](https://github.com/storacha/upload-service/commit/2f6994600e8cc0f70cedc5afe06003a2a0b70af3)) +* add blob protocol to upload-client ([#1425](https://github.com/storacha/upload-service/issues/1425)) ([49aef56](https://github.com/storacha/upload-service/commit/49aef564a726d34dbbedbd83f5366d9320180f99)) +* add blob/get ([#1484](https://github.com/storacha/upload-service/issues/1484)) ([328039d](https://github.com/storacha/upload-service/commit/328039d8a29fec3c1bbab28d1bb9de1643f54f71)) +* add revocation to access-client and w3up-client ([#975](https://github.com/storacha/upload-service/issues/975)) ([6c877aa](https://github.com/storacha/upload-service/commit/6c877aac78eddb924e999dc3270cba010e48e30a)) +* add usage/report capability ([#1079](https://github.com/storacha/upload-service/issues/1079)) ([6418b4b](https://github.com/storacha/upload-service/commit/6418b4b22329a118fb258928bd9a6a45ced5ce45)) +* blob, web3.storage and ucan conclude capabilities together with api handlers ([#1342](https://github.com/storacha/upload-service/issues/1342)) ([00735a8](https://github.com/storacha/upload-service/commit/00735a80dfddbe86359af78ed9bd182f4804691f)) +* **capabilities:** add `index/add` capability ([#1410](https://github.com/storacha/upload-service/issues/1410)) ([1b71b89](https://github.com/storacha/upload-service/commit/1b71b89ed989cde8ef4bf35c1ebc333872cbc54c)) +* change `plan/update` to `plan/set` and use existing `PlansStorage#set` to implement an invocation handler ([#1258](https://github.com/storacha/upload-service/issues/1258)) ([1ccbfe9](https://github.com/storacha/upload-service/commit/1ccbfe9f84ae5b2e99e315c92d15d2b54e9723ba)) +* coupon ([#1136](https://github.com/storacha/upload-service/issues/1136)) ([1b94f2d](https://github.com/storacha/upload-service/commit/1b94f2d3f6538d717d38b21dcb76657fd1f3e268)) +* filecoin info ([#1091](https://github.com/storacha/upload-service/issues/1091)) ([adb2442](https://github.com/storacha/upload-service/commit/adb24424d1faf50daf2339b77c22fdd44faa236a)) +* Generate Space proofs on the fly, on `access/claim` ([#1555](https://github.com/storacha/upload-service/issues/1555)) ([9e2b1d4](https://github.com/storacha/upload-service/commit/9e2b1d4dc721d3e61cea008719d172909c984344)) +* implement `plan/get` capability ([#1005](https://github.com/storacha/upload-service/issues/1005)) ([f0456d2](https://github.com/storacha/upload-service/commit/f0456d2e2aab462666810e22abd7dfb7e1ce21be)) +* introduce capability for changing billing plan ([#1253](https://github.com/storacha/upload-service/issues/1253)) ([d33b3a9](https://github.com/storacha/upload-service/commit/d33b3a9f72a5e7a738d2a084eb19388fa70d9433)) +* move aggregate information out of deals in filecoin/info ([#1192](https://github.com/storacha/upload-service/issues/1192)) ([18dc590](https://github.com/storacha/upload-service/commit/18dc590ad50a023ef3094bfc1a2d729459e5d68e)) +* publish index claim ([#1487](https://github.com/storacha/upload-service/issues/1487)) ([237b0c6](https://github.com/storacha/upload-service/commit/237b0c6cda70ae3e156bac8a011a2739b346ae4b)) +* restrict store API to CARs ([#1415](https://github.com/storacha/upload-service/issues/1415)) ([e53aa87](https://github.com/storacha/upload-service/commit/e53aa87780446458ef9a19c88877073c1470d50e)) +* return allocated bytes in `store/add` receipt ([#1213](https://github.com/storacha/upload-service/issues/1213)) ([5d52e44](https://github.com/storacha/upload-service/commit/5d52e447c14e7f7fd334e7ff575e032b7b0d89d7)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) +* upgrade ucanto/transport to 9.1.0 in all packages to get more verbose errors from HTTP transport on non-ok response ([#1312](https://github.com/storacha/upload-service/issues/1312)) ([d6978d7](https://github.com/storacha/upload-service/commit/d6978d7ab299be76987c6533d18e6857f6998fe6)) +* usage/record capability definition ([#1562](https://github.com/storacha/upload-service/issues/1562)) ([98c8a87](https://github.com/storacha/upload-service/commit/98c8a87c52ef88da728225259e77f65733d2d7e6)) +* wip router ([ffcd9c7](https://github.com/storacha/upload-service/commit/ffcd9c75aee61d37b7fdfc55f2d4b7bee7e9d724)) + + +### Fixes + +* add missing ContentNotFound definition for filecoin offer failure ([c0b97bf](https://github.com/storacha/upload-service/commit/c0b97bf42d87b49d7de11119f9eb6166ab8d97d0)) +* add missing filecoin submit success and failure types ([c0b97bf](https://github.com/storacha/upload-service/commit/c0b97bf42d87b49d7de11119f9eb6166ab8d97d0)) +* capabilities should export blob caps ([#1376](https://github.com/storacha/upload-service/issues/1376)) ([460729e](https://github.com/storacha/upload-service/commit/460729ec296ac2656b264af442b6d3bc25aa8847)) +* client tests ([b0d9c3f](https://github.com/storacha/upload-service/commit/b0d9c3f258d37701487ef02f70a93e2dd1a18775)) +* fix arethetypesworking errors in all packages ([#1004](https://github.com/storacha/upload-service/issues/1004)) ([2e2936a](https://github.com/storacha/upload-service/commit/2e2936a3831389dd13be5be5146a04e2b15553c5)) +* issue where typedoc docs would only show full docs for w3up-client ([#1141](https://github.com/storacha/upload-service/issues/1141)) ([0b8d3f3](https://github.com/storacha/upload-service/commit/0b8d3f3b52918b1b4d3b76ea6fea3fb0c837cd73)) +* migrate repo ([#1389](https://github.com/storacha/upload-service/issues/1389)) ([475a287](https://github.com/storacha/upload-service/commit/475a28743ff9f7138b46dfe4227d3c80ed75a6a2)) +* one more tweak to the `PlanStorage` interface ([#1280](https://github.com/storacha/upload-service/issues/1280)) ([5a44565](https://github.com/storacha/upload-service/commit/5a44565feb33fc08102cd2559a2f22fb0476e86b)) +* package metadata ([#1161](https://github.com/storacha/upload-service/issues/1161)) ([b8a1cc2](https://github.com/storacha/upload-service/commit/b8a1cc2e125a91be582998bda295e1ae1caab087)) +* put access.session back ([#1100](https://github.com/storacha/upload-service/issues/1100)) ([10a1a4b](https://github.com/storacha/upload-service/commit/10a1a4bfc5ec79ea0b7b2049fd7d1953ca0810ef)) +* rename blob and index client capabilities ([#1478](https://github.com/storacha/upload-service/issues/1478)) ([17e3a31](https://github.com/storacha/upload-service/commit/17e3a3161c6585b1844abcf7ed27252fa8580870)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* tests ([b179910](https://github.com/storacha/upload-service/commit/b179910a3b5259a1da0607340d23669c30e34c9e)) +* trigger capabilities release ([#1399](https://github.com/storacha/upload-service/issues/1399)) ([7d9ab35](https://github.com/storacha/upload-service/commit/7d9ab354d194b751bb7f34ffa2f74e7465cb40e2)) +* type errors ([c0b97bf](https://github.com/storacha/upload-service/commit/c0b97bf42d87b49d7de11119f9eb6166ab8d97d0)) +* update data-segment dep ([228ff79](https://github.com/storacha/upload-service/commit/228ff7933219a0bf9ead371bb845d20a4859fda5)) +* upgrade @ucanto/validator with bugfix ([#1151](https://github.com/storacha/upload-service/issues/1151)) ([d4e961b](https://github.com/storacha/upload-service/commit/d4e961bab09e88245e7d9323146849271e78eb57)) +* upgrade ucanto core ([#1127](https://github.com/storacha/upload-service/issues/1127)) ([5ce4d22](https://github.com/storacha/upload-service/commit/5ce4d2292d7e980da4a2ea0f1583f608a81157d2)) +* upgrade ucanto in filecoin api ([c95fb54](https://github.com/storacha/upload-service/commit/c95fb54cdb04f50ff78e5113e70d73c1cd6d8b47)) +* upgrade ucanto libs and format filecoin api ([#1359](https://github.com/storacha/upload-service/issues/1359)) ([87ca098](https://github.com/storacha/upload-service/commit/87ca098186fe204ff3409a2684719f1c54148c97)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* **main:** release capabilities 10.1.0 ([#979](https://github.com/storacha/upload-service/issues/979)) ([bdd3970](https://github.com/storacha/upload-service/commit/bdd39707532ef3f3a38092c0de43a50b8c0ebe66)) +* **main:** release capabilities 10.2.0 ([#983](https://github.com/storacha/upload-service/issues/983)) ([a906488](https://github.com/storacha/upload-service/commit/a906488c8cc36cc981f8703fc156b619fd492e34)) +* **main:** release capabilities 11.0.0 ([#994](https://github.com/storacha/upload-service/issues/994)) ([76b0489](https://github.com/storacha/upload-service/commit/76b048996243cc7bdda62da93342caac13879fa8)) +* **main:** release capabilities 11.0.1 ([#1008](https://github.com/storacha/upload-service/issues/1008)) ([37cdc5a](https://github.com/storacha/upload-service/commit/37cdc5a0662420cb91647559767017d480e5b3d1)) +* **main:** release capabilities 11.1.0 ([#1026](https://github.com/storacha/upload-service/issues/1026)) ([7fdb541](https://github.com/storacha/upload-service/commit/7fdb541fb564dd53dccfcbb318e47ca0f7911476)) +* **main:** release capabilities 11.2.0 ([#1084](https://github.com/storacha/upload-service/issues/1084)) ([0e7b6dc](https://github.com/storacha/upload-service/commit/0e7b6dc17256b50ae05ad9d41b8bd97274f2628d)) +* **main:** release capabilities 11.3.0 ([#1098](https://github.com/storacha/upload-service/issues/1098)) ([7d671bd](https://github.com/storacha/upload-service/commit/7d671bd1ee4ce794c792fdd89fa42399bc7b96a8)) +* **main:** release capabilities 11.3.1 ([#1101](https://github.com/storacha/upload-service/issues/1101)) ([20b5b35](https://github.com/storacha/upload-service/commit/20b5b35a518f7d992d33f0ccf82e257ee61025b0)) +* **main:** release capabilities 11.4.0 ([#1105](https://github.com/storacha/upload-service/issues/1105)) ([1b6210f](https://github.com/storacha/upload-service/commit/1b6210f853c66f8b4aec9b4ff1ecd08316bd6d62)) +* **main:** release capabilities 11.4.1 ([#1131](https://github.com/storacha/upload-service/issues/1131)) ([a5b7154](https://github.com/storacha/upload-service/commit/a5b7154f4702c912fce7bb514a4a27eebe8da7a6)) +* **main:** release capabilities 12.0.0 ([#1137](https://github.com/storacha/upload-service/issues/1137)) ([bb23e9f](https://github.com/storacha/upload-service/commit/bb23e9f8f7a76686b010b50f01739accf642df8b)) +* **main:** release capabilities 12.0.1 ([#1147](https://github.com/storacha/upload-service/issues/1147)) ([d1a9c78](https://github.com/storacha/upload-service/commit/d1a9c782ee79a04c7b6804b6dee70aea2f93de14)) +* **main:** release capabilities 12.0.2 ([#1152](https://github.com/storacha/upload-service/issues/1152)) ([b9d7ff5](https://github.com/storacha/upload-service/commit/b9d7ff5008db1db0c6f552871b091856f2f9de39)) +* **main:** release capabilities 12.0.3 ([#1163](https://github.com/storacha/upload-service/issues/1163)) ([ec5c385](https://github.com/storacha/upload-service/commit/ec5c3855cd7eb64fe9114a2f116fcd52956a0ae6)) +* **main:** release capabilities 12.1.0 ([#1195](https://github.com/storacha/upload-service/issues/1195)) ([a21c1a5](https://github.com/storacha/upload-service/commit/a21c1a524bf5d9941b877f1d6f7707ab83499736)) +* **main:** release capabilities 13.0.0 ([#1230](https://github.com/storacha/upload-service/issues/1230)) ([3d5b3ef](https://github.com/storacha/upload-service/commit/3d5b3ef93349a0d0c1b7e1b198e3f400a82c0f72)) +* **main:** release capabilities 13.1.0 ([#1257](https://github.com/storacha/upload-service/issues/1257)) ([85adc9a](https://github.com/storacha/upload-service/commit/85adc9a7dcdf66534e0c44997658f18bae36ab67)) +* **main:** release capabilities 13.1.1 ([#1283](https://github.com/storacha/upload-service/issues/1283)) ([31c38e9](https://github.com/storacha/upload-service/commit/31c38e9d6f5eda4c98dfa7441dc8fe98c56985dc)) +* **main:** release capabilities 13.2.0 ([#1315](https://github.com/storacha/upload-service/issues/1315)) ([0505458](https://github.com/storacha/upload-service/commit/0505458d27da4e3233b1ecef1b3090a1f2cf5155)) +* **main:** release capabilities 13.2.1 ([#1362](https://github.com/storacha/upload-service/issues/1362)) ([26b5751](https://github.com/storacha/upload-service/commit/26b5751e36fb609e565e212e03bb2b8fced31e9e)) +* **main:** release capabilities 13.3.0 ([#1366](https://github.com/storacha/upload-service/issues/1366)) ([d6fbc4a](https://github.com/storacha/upload-service/commit/d6fbc4a4ac05d071cda9701a68fe0776a97144ae)) +* **main:** release capabilities 13.3.1 ([#1377](https://github.com/storacha/upload-service/issues/1377)) ([149f592](https://github.com/storacha/upload-service/commit/149f5920effc3e994168082dbb6dc614418b8a63)) +* **main:** release capabilities 14.0.0 ([#1386](https://github.com/storacha/upload-service/issues/1386)) ([69bfc08](https://github.com/storacha/upload-service/commit/69bfc0869afaad1dc09bf0d6b2e891c786ffc6ef)) +* **main:** release capabilities 14.0.1 ([#1395](https://github.com/storacha/upload-service/issues/1395)) ([a76c970](https://github.com/storacha/upload-service/commit/a76c970446c347ea5aed7e7806f6039683038283)) +* **main:** release capabilities 14.0.2 ([#1400](https://github.com/storacha/upload-service/issues/1400)) ([7b46852](https://github.com/storacha/upload-service/commit/7b4685294d1ab40a3da71053af2481a2376d76fe)) +* **main:** release capabilities 15.0.0 ([#1412](https://github.com/storacha/upload-service/issues/1412)) ([ec90b81](https://github.com/storacha/upload-service/commit/ec90b810833ae65810a4327f0e80b52722b137de)) +* **main:** release capabilities 16.0.0 ([#1419](https://github.com/storacha/upload-service/issues/1419)) ([50e3934](https://github.com/storacha/upload-service/commit/50e39340b9ca761d0fbb3a783d2c32120483db52)) +* **main:** release capabilities 17.0.0 ([#1428](https://github.com/storacha/upload-service/issues/1428)) ([6ee21fd](https://github.com/storacha/upload-service/commit/6ee21fdb37e33395eefc755eec8aefb81622d4cb)) +* **main:** release capabilities 17.1.0 ([#1447](https://github.com/storacha/upload-service/issues/1447)) ([8ee1fd9](https://github.com/storacha/upload-service/commit/8ee1fd9d71a9a8897be25826f0945b310acc9100)) +* **main:** release capabilities 17.1.1 ([#1483](https://github.com/storacha/upload-service/issues/1483)) ([5394ed5](https://github.com/storacha/upload-service/commit/5394ed5f77baf6f16e9d0fb5b5e6f2f8e823ecf2)) +* **main:** release capabilities 17.2.0 ([#1494](https://github.com/storacha/upload-service/issues/1494)) ([99876a5](https://github.com/storacha/upload-service/commit/99876a5a3f936a43e838a5fc847761e24bc43abc)) +* **main:** release capabilities 17.3.0 ([#1503](https://github.com/storacha/upload-service/issues/1503)) ([891c2a5](https://github.com/storacha/upload-service/commit/891c2a56096b3565feb842bb6be16ceaec4df1f8)) +* **main:** release capabilities 17.4.0 ([#1559](https://github.com/storacha/upload-service/issues/1559)) ([feaea7a](https://github.com/storacha/upload-service/commit/feaea7a0736dbfbb23114d1693f8d70e4eafdc3f)) +* no longer depends on hd-scripts, packages use/configure eslint directly, fixes warnings from npm lint script ([#1058](https://github.com/storacha/upload-service/issues/1058)) ([ebdb99b](https://github.com/storacha/upload-service/commit/ebdb99b0d3fc912f93ace3d533b915f844b35856)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [17.4.0](https://github.com/storacha/w3up/compare/capabilities-v17.3.0...capabilities-v17.4.0) (2024-10-24) diff --git a/packages/capabilities/package.json b/packages/capabilities/package.json index 59bb838a2..272fcbba7 100644 --- a/packages/capabilities/package.json +++ b/packages/capabilities/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/capabilities", - "version": "17.4.0", - "description": "UCAN Capabilities provided by web3.storage", - "homepage": "https://web3.storage", + "name": "@storacha/capabilities", + "version": "1.2.1", + "description": "UCAN Capabilities provided by storacha.network", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/capabilities" }, "license": "(Apache-2.0 OR MIT)", @@ -37,6 +37,10 @@ "types": "./dist/test/helpers/*.d.ts", "import": "./test/helpers/*.js" }, + "./blob": { + "types": "./dist/src/blob.d.ts", + "import": "./src/blob.js" + }, "./filecoin": { "types": "./dist/src/filecoin/index.d.ts", "import": "./src/filecoin/index.js" @@ -57,9 +61,13 @@ "types": "./dist/src/filecoin/dealer.d.ts", "import": "./src/filecoin/dealer.js" }, - "./index": { - "types": "./dist/src/index/index.d.ts", - "import": "./src/index/index.js" + "./space/index": { + "types": "./dist/src/space/index.d.ts", + "import": "./src/space/index.js" + }, + "./space/blob": { + "types": "./dist/src/space/blob.d.ts", + "import": "./src/space/blob.js" }, "./web3.storage/blob": { "types": "./dist/src/web3.storage/blob.d.ts", @@ -92,19 +100,20 @@ "dist/src/**/*.d.ts.map" ], "dependencies": { - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/principal": "^9.0.1", + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/principal": "^9.0.2", "@ucanto/transport": "^9.1.1", - "@ucanto/validator": "^9.0.2", + "@ucanto/validator": "^9.0.3", "@web3-storage/data-segment": "^5.2.0", "uint8arrays": "^5.0.3" }, "devDependencies": { + "@ipld/dag-ucan": "^3.4.5", + "@storacha/eslint-config": "workspace:^", "@types/assert": "^1.5.6", "@types/mocha": "^10.0.0", "@types/node": "^20.8.4", - "@web3-storage/eslint-config-w3up": "workspace:^", "assert": "^2.0.0", "mocha": "^10.2.0", "playwright-test": "^12.3.4", @@ -114,7 +123,7 @@ }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -139,7 +148,7 @@ "ignores": [ "@types/*", "assert", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] } } diff --git a/packages/capabilities/readme.md b/packages/capabilities/readme.md index ad7407384..eee87dd7f 100644 --- a/packages/capabilities/readme.md +++ b/packages/capabilities/readme.md @@ -1,38 +1,38 @@ -# ⁂ `@web3-storage/capabilities` +# ⁂ `@storacha/capabilities` -[Capabilities](https://en.wikipedia.org/wiki/Capability-based_security) for interacting with [web3.storage](https://web3.storage) +[Capabilities](https://en.wikipedia.org/wiki/Capability-based_security) for interacting with [storacha.network](https://storacha.network) ## About -The w3up platform by [web3.storage](https://web3.storage) is implemented as a set of capabilities that can be invoked using the [ucanto](https://github.com/storacha/ucanto) RPC framework. +The w3up platform by [storacha.network](https://storacha.network) is implemented as a set of capabilities that can be invoked using the [ucanto](https://github.com/storacha/ucanto) RPC framework. -The `@web3-storage/capabilities` package contains capability definitions, which are used by clients to create invocations and by services to validate and parse invocations and route requests to the correct capability handler. +The `@storacha/capabilities` package contains capability definitions, which are used by clients to create invocations and by services to validate and parse invocations and route requests to the correct capability handler. -See the [capabilities spec](https://github.com/storacha/w3up/tree/main/spec/capabilities.md) for more information about each capability included in this package. +See the [capabilities spec](https://github.com/storacha/upload-service/tree/main/spec/capabilities.md) for more information about each capability included in this package. ## Install Install the package: ```bash -npm install @web3-storage/capabilities +npm install @storacha/capabilities ``` ## Usage ```js -import * as Space from '@web3-storage/capabilities/space' -import * as Store from '@web3-storage/capabilities/store' -import * as Top from '@web3-storage/capabilities/top' -import * as Types from '@web3-storage/capabilities/types' -import * as Upload from '@web3-storage/capabilities/upload' -import * as Utils from '@web3-storage/capabilities/utils' -import * as Plan from '@web3-storage/capabilities/plan' -import * as Filecoin from '@web3-storage/capabilities/filecoin' -import * as Aggregator from '@web3-storage/capabilities/filecoin/aggregator' -import * as DealTracker from '@web3-storage/capabilities/filecoin/deal-tracker' -import * as Dealer from '@web3-storage/capabilities/filecoin/dealer' -import * as Index from '@web3-storage/capabilities/index' +import * as Space from '@storacha/capabilities/space' +import * as Store from '@storacha/capabilities/store' +import * as Top from '@storacha/capabilities/top' +import * as Types from '@storacha/capabilities/types' +import * as Upload from '@storacha/capabilities/upload' +import * as Utils from '@storacha/capabilities/utils' +import * as Plan from '@storacha/capabilities/plan' +import * as Filecoin from '@storacha/capabilities/filecoin' +import * as Aggregator from '@storacha/capabilities/filecoin/aggregator' +import * as DealTracker from '@storacha/capabilities/filecoin/deal-tracker' +import * as Dealer from '@storacha/capabilities/filecoin/dealer' +import * as Index from '@storacha/capabilities/space/index' // This package has a "main" entrypoint but we recommend the usage of the specific imports above ``` @@ -115,14 +115,14 @@ interface UCANOptions { } ``` -In the example below, we're generating a new `Signer` to act as the issuer of the invocation using the `@ucanto/principal/ed25519` package. Note that in a real application, the service would likely reject an invocation from this signer, as it does not have any delegated permissions. See the [access client package](https://github.com/storacha/w3up/tree/main/packages/access-client) for more about key management and delegation in practice. +In the example below, we're generating a new `Signer` to act as the issuer of the invocation using the `@ucanto/principal/ed25519` package. Note that in a real application, the service would likely reject an invocation from this signer, as it does not have any delegated permissions. See the [access client package](https://github.com/storacha/upload-service/tree/main/packages/access-client) for more about key management and delegation in practice. ```ts import * as DID from '@ipld/dag-ucan/did' import * as ed25519 from '@ucanto/principal/ed25519' const issuer = await ed25519.generate() -const audience = DID.parse('did:web:web3.storage') +const audience = DID.parse('did:web:storacha.network') const invocation = Store.add.invoke({ issuer, @@ -152,7 +152,7 @@ import * as DID from '@ipld/dag-ucan/did' import * as ed25519 from '@ucanto/principal/ed25519' const issuer = await ed25519.generate() -const audience = DID.parse('did:web:web3.storage') +const audience = DID.parse('did:web:storacha.network') const delegation = await Store.add.delegate({ issuer, diff --git a/packages/capabilities/src/access.js b/packages/capabilities/src/access.js index 9be0dbfc7..731111dac 100644 --- a/packages/capabilities/src/access.js +++ b/packages/capabilities/src/access.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Access from '@web3-storage/capabilities/access' + * import * as Access from '@storacha/capabilities/access' * ``` * * @module diff --git a/packages/capabilities/src/blob.js b/packages/capabilities/src/blob.js index 6af1ae576..592696962 100644 --- a/packages/capabilities/src/blob.js +++ b/packages/capabilities/src/blob.js @@ -1,177 +1,81 @@ /** * Blob Capabilities. * - * Blob is a fixed size byte array addressed by the multihash. - * Usually blobs are used to represent set of IPLD blocks at different byte ranges. + * The blob protocol allows authorized agents allocate memory space on a storage + * node and subsequently verify the content has been accepted by / delivered to + * said node. * * These can be imported directly with: * ```js - * import * as Blob from '@web3-storage/capabilities/blob' + * import * as Index from '@storacha/capabilities/blob' * ``` * * @module + * @see https://github.com/storacha/specs/blob/main/w3-blob.md */ -import { equals } from 'uint8arrays/equals' -import { capability, Schema, fail, ok } from '@ucanto/validator' -import { equalBlob, equalWith, SpaceDID } from './utils.js' - -/** - * Agent capabilities for Blob protocol - */ +import { capability, Schema, Link, ok } from '@ucanto/validator' +import { content } from './space/blob.js' +import { equalBlob, equalWith, and, equal, checkLink, Await } from './utils.js' /** * Capability can only be delegated (but not invoked) allowing audience to - * derived any `space/blob/` prefixed capability for the (memory) space identified - * by DID in the `with` field. + * derive any `blob/` prefixed capability. */ export const blob = capability({ - can: 'space/blob/*', - /** - * DID of the (memory) space where Blob is intended to - * be stored. - */ - with: SpaceDID, + can: 'blob/*', + /** Storage provider DID. */ + with: Schema.did(), derives: equalWith, }) /** - * Blob description for being ingested by the service. - */ -export const content = Schema.struct({ - /** - * A multihash digest of the blob payload bytes, uniquely identifying blob. - */ - digest: Schema.bytes(), - /** - * Number of bytes contained by this blob. Service will provision write target - * for this exact size. Attempt to write a larger Blob file will fail. - */ - size: Schema.integer(), -}) - -/** - * `space/blob/add` capability allows agent to store a Blob into a (memory) space - * identified by did:key in the `with` field. Agent should compute blob multihash - * and size and provide it under `nb.blob` field, allowing a service to provision - * a write location for the agent to PUT desired Blob into. + * The `blob/allocate` capability can be invoked to create a memory address on a + * storage node where blob content can be written via a HTTP PUT request. */ -export const add = capability({ - can: 'space/blob/add', - /** - * DID of the (memory) space where Blob is intended to - * be stored. - */ - with: SpaceDID, +export const allocate = capability({ + can: 'blob/allocate', + /** Storage provider DID. */ + with: Schema.did(), nb: Schema.struct({ - /** - * Blob to be added on the space. - */ + /** Blob to allocate. */ blob: content, + /** Link to the add blob task that initiated the allocation. */ + cause: Schema.link({ version: 1 }), + /** DID of the user space where the allocation takes place. */ + space: Schema.bytes(), }), - derives: equalBlob, -}) - -/** - * Capability can be used to remove the stored Blob from the (memory) - * space identified by `with` field. - */ -export const remove = capability({ - can: 'space/blob/remove', - /** - * DID of the (memory) space where Blob is stored. - */ - with: SpaceDID, - nb: Schema.struct({ - /** - * A multihash digest of the blob payload bytes, uniquely identifying blob. - */ - digest: Schema.bytes(), - }), - derives: (claimed, delegated) => { - if (claimed.with !== delegated.with) { - return fail( - `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` - ) - } else if ( - delegated.nb.digest && - !equals(delegated.nb.digest, claimed.nb.digest) - ) { - return fail( - `Link ${ - claimed.nb.digest ? `${claimed.nb.digest}` : '' - } violates imposed ${delegated.nb.digest} constraint.` - ) - } - return ok({}) - }, -}) - -/** - * Capability can be invoked to request a list of stored Blobs in the - * (memory) space identified by `with` field. - */ -export const list = capability({ - can: 'space/blob/list', - /** - * DID of the (memory) space where Blobs to be listed are stored. - */ - with: SpaceDID, - nb: Schema.struct({ - /** - * A pointer that can be moved back and forth on the list. - * It can be used to paginate a list for instance. - */ - cursor: Schema.string().optional(), - /** - * Maximum number of items per page. - */ - size: Schema.integer().optional(), - }), - derives: (claimed, delegated) => { - if (claimed.with !== delegated.with) { - return fail( - `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` - ) - } - return ok({}) - }, + derives: (claimed, delegated) => + and(equalWith(claimed, delegated)) || + and(equalBlob(claimed, delegated)) || + and(checkLink(claimed.nb.cause, delegated.nb.cause, 'cause')) || + and(equal(claimed.nb.space, delegated.nb.space, 'space')) || + ok({}), }) /** - * Capability can be used to get the stored Blob from the (memory) - * space identified by `with` field. + * The `blob/accept` capability invocation should either succeed when content is + * delivered on allocated address or fail if no content is allocation expires + * without content being delivered. */ -export const get = capability({ - can: 'space/blob/get/0/1', - /** - * DID of the (memory) space where Blob is stored. - */ - with: SpaceDID, +export const accept = capability({ + can: 'blob/accept', + /** Storage provider DID. */ + with: Schema.did(), nb: Schema.struct({ - /** - * A multihash digest of the blob payload bytes, uniquely identifying blob. - */ - digest: Schema.bytes(), + /** Blob to accept. */ + blob: content, + /** DID of the user space where allocation took place. */ + space: Schema.bytes(), + /** This task is blocked on `http/put` receipt available */ + _put: Await, }), - derives: (claimed, delegated) => { - if (claimed.with !== delegated.with) { - return fail( - `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` - ) - } else if ( - delegated.nb.digest && - !equals(delegated.nb.digest, claimed.nb.digest) - ) { - return fail( - `Link ${ - claimed.nb.digest ? `${claimed.nb.digest}` : '' - } violates imposed ${delegated.nb.digest} constraint.` - ) - } - return ok({}) - }, + derives: (claimed, delegated) => + and(equalWith(claimed, delegated)) || + and(equalBlob(claimed, delegated)) || + and(equal(claimed.nb.space, delegated.nb.space, 'space')) || + ok({}), }) // ⚠️ We export imports here so they are not omitted in generated typedefs // @see https://github.com/microsoft/TypeScript/issues/51548 -export { Schema } +export { Schema, Link } diff --git a/packages/capabilities/src/consumer.js b/packages/capabilities/src/consumer.js index 8e04d3d67..1f4c70a43 100644 --- a/packages/capabilities/src/consumer.js +++ b/packages/capabilities/src/consumer.js @@ -1,7 +1,7 @@ import { capability, DID, struct, ok } from '@ucanto/validator' import { equalWith, and, equal, SpaceDID } from './utils.js' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const ProviderDID = DID.match({ method: 'web' }) /** diff --git a/packages/capabilities/src/customer.js b/packages/capabilities/src/customer.js index b9d50254f..d9c249927 100644 --- a/packages/capabilities/src/customer.js +++ b/packages/capabilities/src/customer.js @@ -1,7 +1,7 @@ import { capability, DID, struct, ok } from '@ucanto/validator' import { AccountDID, equalWith, and, equal } from './utils.js' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const ProviderDID = DID.match({ method: 'web' }) /** diff --git a/packages/capabilities/src/filecoin/aggregator.js b/packages/capabilities/src/filecoin/aggregator.js index 64d5432bd..cd9c341a8 100644 --- a/packages/capabilities/src/filecoin/aggregator.js +++ b/packages/capabilities/src/filecoin/aggregator.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Aggregator from '@web3-storage/capabilities/filecoin/aggregator' + * import * as Aggregator from '@storacha/capabilities/filecoin/aggregator' * ``` * * @module diff --git a/packages/capabilities/src/filecoin/deal-tracker.js b/packages/capabilities/src/filecoin/deal-tracker.js index f656394d5..871c652cd 100644 --- a/packages/capabilities/src/filecoin/deal-tracker.js +++ b/packages/capabilities/src/filecoin/deal-tracker.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as DealTracker from '@web3-storage/capabilities/filecoin/deal-tracker' + * import * as DealTracker from '@storacha/capabilities/filecoin/deal-tracker' * ``` * * @module diff --git a/packages/capabilities/src/filecoin/dealer.js b/packages/capabilities/src/filecoin/dealer.js index ca456fe65..4c49af33f 100644 --- a/packages/capabilities/src/filecoin/dealer.js +++ b/packages/capabilities/src/filecoin/dealer.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Dealer from '@web3-storage/capabilities/filecoin/dealer' + * import * as Dealer from '@storacha/capabilities/filecoin/dealer' * ``` * * @module diff --git a/packages/capabilities/src/filecoin/index.js b/packages/capabilities/src/filecoin/index.js index aee774398..00716be48 100644 --- a/packages/capabilities/src/filecoin/index.js +++ b/packages/capabilities/src/filecoin/index.js @@ -6,7 +6,7 @@ * * These can be imported directly with: * ```js - * import * as Filecoin from '@web3-storage/capabilities/filecoin' + * import * as Filecoin from '@storacha/capabilities/filecoin' * ``` * * @module @@ -17,4 +17,5 @@ export { filecoinSubmit as submit, filecoinAccept as accept, filecoinInfo as info, + filecoin as filecoin, } from './storefront.js' diff --git a/packages/capabilities/src/filecoin/storefront.js b/packages/capabilities/src/filecoin/storefront.js index 53f0cc4b3..d8f1a9611 100644 --- a/packages/capabilities/src/filecoin/storefront.js +++ b/packages/capabilities/src/filecoin/storefront.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Storefront from '@web3-storage/capabilities/filecoin/storefront' + * import * as Storefront from '@storacha/capabilities/filecoin/storefront' * ``` * * @module @@ -13,6 +13,18 @@ import { capability, Schema, ok } from '@ucanto/validator' import { PieceLink } from './lib.js' import { equalWith, checkLink, and } from '../utils.js' +/** + * Top-level capability for Filecoin operations. + */ +export const filecoin = capability({ + can: 'filecoin/*', + /** + * DID of the space the content is stored in. + */ + with: Schema.did(), + derives: equalWith, +}) + /** * Capability allowing an agent to _request_ storing a content piece in * Filecoin. diff --git a/packages/capabilities/src/http.js b/packages/capabilities/src/http.js index a20b025f8..0d60a4e7a 100644 --- a/packages/capabilities/src/http.js +++ b/packages/capabilities/src/http.js @@ -3,13 +3,13 @@ * * These can be imported directly with: * ```js - * import * as HTTP from '@web3-storage/capabilities/http' + * import * as HTTP from '@storacha/capabilities/http' * ``` * * @module */ import { capability, Schema, ok } from '@ucanto/validator' -import { content } from './blob.js' +import { content } from './space/blob.js' import { equal, equalBody, equalWith, SpaceDID, Await, and } from './utils.js' /** diff --git a/packages/capabilities/src/index.js b/packages/capabilities/src/index.js index beb10efb8..63a82e415 100644 --- a/packages/capabilities/src/index.js +++ b/packages/capabilities/src/index.js @@ -16,11 +16,12 @@ import * as Storefront from './filecoin/storefront.js' import * as Aggregator from './filecoin/aggregator.js' import * as Dealer from './filecoin/dealer.js' import * as DealTracker from './filecoin/deal-tracker.js' -import * as Index from './index/index.js' +import * as SpaceIndex from './space/index.js' import * as UCAN from './ucan.js' import * as Plan from './plan.js' import * as Usage from './usage.js' import * as Blob from './blob.js' +import * as SpaceBlob from './space/blob.js' import * as W3sBlob from './web3.storage/blob.js' import * as HTTP from './http.js' @@ -38,7 +39,7 @@ export { RateLimit, Subscription, Filecoin, - Index, + SpaceIndex, Storefront, Aggregator, Dealer, @@ -48,6 +49,7 @@ export { Plan, Usage, Blob, + SpaceBlob, W3sBlob, HTTP, } @@ -98,13 +100,16 @@ export const abilitiesAsStrings = [ Usage.usage.can, Usage.report.can, Blob.blob.can, - Blob.add.can, - Blob.remove.can, - Blob.list.can, + Blob.allocate.can, + Blob.accept.can, + SpaceBlob.blob.can, + SpaceBlob.add.can, + SpaceBlob.remove.can, + SpaceBlob.list.can, W3sBlob.blob.can, W3sBlob.allocate.can, W3sBlob.accept.can, HTTP.put.can, - Index.index.can, - Index.add.can, + SpaceIndex.index.can, + SpaceIndex.add.can, ] diff --git a/packages/capabilities/src/provider.js b/packages/capabilities/src/provider.js index e217a6499..5cba0a20a 100644 --- a/packages/capabilities/src/provider.js +++ b/packages/capabilities/src/provider.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Provider from '@web3-storage/capabilities/provider' + * import * as Provider from '@storacha/capabilities/provider' * ``` * * @module @@ -11,7 +11,7 @@ import { capability, DID, struct, ok } from '@ucanto/validator' import { AccountDID, equalWith, and, equal, SpaceDID } from './utils.js' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const Provider = DID.match({ method: 'web' }) export { AccountDID } diff --git a/packages/capabilities/src/rate-limit.js b/packages/capabilities/src/rate-limit.js index 71d3b380d..d9e1ecd71 100644 --- a/packages/capabilities/src/rate-limit.js +++ b/packages/capabilities/src/rate-limit.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as RateLimit from '@web3-storage/capabilities/rate-limit' + * import * as RateLimit from '@storacha/capabilities/rate-limit' * ``` * * @module @@ -11,7 +11,7 @@ import { capability, DID, struct, Schema, ok } from '@ucanto/validator' import { equalWith, and, equal } from './utils.js' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const Provider = DID /** diff --git a/packages/capabilities/src/space.js b/packages/capabilities/src/space.js index 704e2cf66..fe4d62612 100644 --- a/packages/capabilities/src/space.js +++ b/packages/capabilities/src/space.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Space from '@web3-storage/capabilities/space' + * import * as Space from '@storacha/capabilities/space' * ``` * * @module @@ -63,3 +63,32 @@ export const allocate = capability({ } }, }) + +/** + * The capability grants permission for all content serve operations that fall under the "space/content/serve" namespace. + * It can be derived from any of the `space/*` capability that has matching `with`. + */ + +export const contentServe = capability({ + can: 'space/content/serve/*', + with: SpaceDID, + derives: equalWith, +}) + +/** + * Capability can be invoked by an agent to record egress data for a given resource. + * It can be derived from any of the `space/content/serve/*` capability that has matching `with`. + */ +export const egressRecord = capability({ + can: 'space/content/serve/egress/record', + with: SpaceDID, + nb: Schema.struct({ + /** CID of the resource that was served. */ + resource: Schema.link(), + /** Amount of bytes served. */ + bytes: Schema.integer().greaterThan(0), + /** Timestamp of the event in milliseconds after Unix epoch. */ + servedAt: Schema.integer().greaterThan(-1), + }), + derives: equalWith, +}) diff --git a/packages/capabilities/src/space/blob.js b/packages/capabilities/src/space/blob.js new file mode 100644 index 000000000..0d6b3bb67 --- /dev/null +++ b/packages/capabilities/src/space/blob.js @@ -0,0 +1,177 @@ +/** + * Blob Capabilities. + * + * Blob is a fixed size byte array addressed by the multihash. + * Usually blobs are used to represent set of IPLD blocks at different byte ranges. + * + * These can be imported directly with: + * ```js + * import * as Blob from '@storacha/capabilities/space/blob' + * ``` + * + * @module + */ +import { equals as SpaceBlobCapabilities } from 'uint8arrays/equals' +import { capability, Schema, fail, ok } from '@ucanto/validator' +import { equalBlob, equalWith, SpaceDID } from '../utils.js' + +/** + * Agent capabilities for Blob protocol + */ + +/** + * Capability can only be delegated (but not invoked) allowing audience to + * derived any `space/blob/` prefixed capability for the (memory) space identified + * by DID in the `with` field. + */ +export const blob = capability({ + can: 'space/blob/*', + /** + * DID of the (memory) space where Blob is intended to + * be stored. + */ + with: SpaceDID, + derives: equalWith, +}) + +/** + * Blob description for being ingested by the service. + */ +export const content = Schema.struct({ + /** + * A multihash digest of the blob payload bytes, uniquely identifying blob. + */ + digest: Schema.bytes(), + /** + * Number of bytes contained by this blob. Service will provision write target + * for this exact size. Attempt to write a larger Blob file will fail. + */ + size: Schema.integer(), +}) + +/** + * `space/blob/add` capability allows agent to store a Blob into a (memory) space + * identified by did:key in the `with` field. Agent should compute blob multihash + * and size and provide it under `nb.blob` field, allowing a service to provision + * a write location for the agent to PUT desired Blob into. + */ +export const add = capability({ + can: 'space/blob/add', + /** + * DID of the (memory) space where Blob is intended to + * be stored. + */ + with: SpaceDID, + nb: Schema.struct({ + /** + * Blob to be added on the space. + */ + blob: content, + }), + derives: equalBlob, +}) + +/** + * Capability can be used to remove the stored Blob from the (memory) + * space identified by `with` field. + */ +export const remove = capability({ + can: 'space/blob/remove', + /** + * DID of the (memory) space where Blob is stored. + */ + with: SpaceDID, + nb: Schema.struct({ + /** + * A multihash digest of the blob payload bytes, uniquely identifying blob. + */ + digest: Schema.bytes(), + }), + derives: (claimed, delegated) => { + if (claimed.with !== delegated.with) { + return fail( + `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` + ) + } else if ( + delegated.nb.digest && + !SpaceBlobCapabilities(delegated.nb.digest, claimed.nb.digest) + ) { + return fail( + `Link ${ + claimed.nb.digest ? `${claimed.nb.digest}` : '' + } violates imposed ${delegated.nb.digest} constraint.` + ) + } + return ok({}) + }, +}) + +/** + * Capability can be invoked to request a list of stored Blobs in the + * (memory) space identified by `with` field. + */ +export const list = capability({ + can: 'space/blob/list', + /** + * DID of the (memory) space where Blobs to be listed are stored. + */ + with: SpaceDID, + nb: Schema.struct({ + /** + * A pointer that can be moved back and forth on the list. + * It can be used to paginate a list for instance. + */ + cursor: Schema.string().optional(), + /** + * Maximum number of items per page. + */ + size: Schema.integer().optional(), + }), + derives: (claimed, delegated) => { + if (claimed.with !== delegated.with) { + return fail( + `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` + ) + } + return ok({}) + }, +}) + +/** + * Capability can be used to get the stored Blob from the (memory) + * space identified by `with` field. + */ +export const get = capability({ + can: 'space/blob/get/0/1', + /** + * DID of the (memory) space where Blob is stored. + */ + with: SpaceDID, + nb: Schema.struct({ + /** + * A multihash digest of the blob payload bytes, uniquely identifying blob. + */ + digest: Schema.bytes(), + }), + derives: (claimed, delegated) => { + if (claimed.with !== delegated.with) { + return fail( + `Expected 'with: "${delegated.with}"' instead got '${claimed.with}'` + ) + } else if ( + delegated.nb.digest && + !SpaceBlobCapabilities(delegated.nb.digest, claimed.nb.digest) + ) { + return fail( + `Link ${ + claimed.nb.digest ? `${claimed.nb.digest}` : '' + } violates imposed ${delegated.nb.digest} constraint.` + ) + } + return ok({}) + }, +}) + +// ⚠️ We export imports here so they are not omitted in generated typedefs +// @see https://github.com/microsoft/TypeScript/issues/51548 +export { Schema } diff --git a/packages/capabilities/src/index/index.js b/packages/capabilities/src/space/index.js similarity index 89% rename from packages/capabilities/src/index/index.js rename to packages/capabilities/src/space/index.js index d11a81352..62020a4e8 100644 --- a/packages/capabilities/src/index/index.js +++ b/packages/capabilities/src/space/index.js @@ -7,12 +7,12 @@ * * These can be imported directly with: * ```js - * import * as Index from '@web3-storage/capabilities/index' + * import * as Index from '@storacha/capabilities/space/index' * ``` * * @module */ -import { CAR } from '@ucanto/core' +import { CAR as SpaceIndex } from '@ucanto/core' import { capability, Schema, ok } from '@ucanto/validator' import { equalWith, SpaceDID, and, equal } from '../utils.js' @@ -39,7 +39,7 @@ export const add = capability({ with: SpaceDID, nb: Schema.struct({ /** Content Archive (CAR) containing the `Index`. */ - index: Schema.link({ code: CAR.code, version: 1 }), + index: Schema.link({ code: SpaceIndex.code, version: 1 }), }), derives: (claimed, delegated) => and(equalWith(claimed, delegated)) || diff --git a/packages/capabilities/src/store.js b/packages/capabilities/src/store.js index 9e143d068..66d9c3a8f 100644 --- a/packages/capabilities/src/store.js +++ b/packages/capabilities/src/store.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Store from '@web3-storage/capabilities/store' + * import * as Store from '@storacha/capabilities/store' * ``` * * @module diff --git a/packages/capabilities/src/subscription.js b/packages/capabilities/src/subscription.js index ffda0fb72..feca9088d 100644 --- a/packages/capabilities/src/subscription.js +++ b/packages/capabilities/src/subscription.js @@ -1,7 +1,7 @@ import { capability, DID, struct, ok, Schema } from '@ucanto/validator' import { AccountDID, equalWith, and, equal } from './utils.js' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const ProviderDID = DID.match({ method: 'web' }) /** diff --git a/packages/capabilities/src/top.js b/packages/capabilities/src/top.js index 3134de58f..dd56ba6c3 100644 --- a/packages/capabilities/src/top.js +++ b/packages/capabilities/src/top.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Account from '@web3-storage/capabilities/top' + * import * as Account from '@storacha/capabilities/top' * ``` * * @module diff --git a/packages/capabilities/src/types.ts b/packages/capabilities/src/types.ts index 7704922e3..36a0b915e 100644 --- a/packages/capabilities/src/types.ts +++ b/packages/capabilities/src/types.ts @@ -18,10 +18,11 @@ import { ProofData, uint64, } from '@web3-storage/data-segment' -import { space, info } from './space.js' +import * as SpaceCaps from './space.js' import * as provider from './provider.js' import { top } from './top.js' import * as BlobCaps from './blob.js' +import * as SpaceBlobCaps from './space/blob.js' import * as W3sBlobCaps from './web3.storage/blob.js' import * as HTTPCaps from './http.js' import * as StoreCaps from './store.js' @@ -35,7 +36,7 @@ import * as StorefrontCaps from './filecoin/storefront.js' import * as AggregatorCaps from './filecoin/aggregator.js' import * as DealTrackerCaps from './filecoin/deal-tracker.js' import * as DealerCaps from './filecoin/dealer.js' -import * as IndexCaps from './index/index.js' +import * as SpaceIndexCaps from './space/index.js' import * as AdminCaps from './admin.js' import * as UCANCaps from './ucan.js' import * as PlanCaps from './plan.js' @@ -131,12 +132,8 @@ export type UsageReport = InferInvokedCapability export type UsageReportSuccess = Record export type UsageReportFailure = Ucanto.Failure -export type EgressRecord = InferInvokedCapability -export type EgressRecordSuccess = Unit -export type EgressRecordFailure = ConsumerNotFound | Ucanto.Failure - export interface UsageData { - /** Provider the report concerns, e.g. `did:web:web3.storage` */ + /** Provider the report concerns, e.g. `did:web:storacha.network` */ provider: ProviderDID /** Space the report concerns. */ space: SpaceDID @@ -276,8 +273,20 @@ export interface RateLimitListSuccess { export type RateLimitListFailure = Ucanto.Failure // Space -export type Space = InferInvokedCapability -export type SpaceInfo = InferInvokedCapability +export type Space = InferInvokedCapability +export type SpaceInfo = InferInvokedCapability +export type SpaceContentServe = InferInvokedCapability< + typeof SpaceCaps.contentServe +> +export type EgressRecord = InferInvokedCapability +export type EgressRecordSuccess = { + space: SpaceDID + resource: UnknownLink + bytes: number + servedAt: ISO8601Date + cause: UnknownLink +} +export type EgressRecordFailure = ConsumerNotFound | Ucanto.Failure // filecoin export interface DealMetadata { @@ -473,12 +482,12 @@ export type UploadGetFailure = UploadNotFound | Ucanto.Failure export type HTTPPut = InferInvokedCapability // Index -export type Index = InferInvokedCapability -export type IndexAdd = InferInvokedCapability +export type SpaceIndex = InferInvokedCapability +export type SpaceIndexAdd = InferInvokedCapability -export type IndexAddSuccess = Unit +export type SpaceIndexAddSuccess = Unit -export type IndexAddFailure = +export type SpaceIndexAddFailure = | IndexNotFound | DecodeFailure | UnknownFormat @@ -519,13 +528,20 @@ export interface SliceNotFound extends Failure { // Blob export type Blob = InferInvokedCapability -export type BlobAdd = InferInvokedCapability -export type BlobRemove = InferInvokedCapability -export type BlobList = InferInvokedCapability -export type BlobGet = InferInvokedCapability -export type ServiceBlob = InferInvokedCapability -export type BlobAllocate = InferInvokedCapability -export type BlobAccept = InferInvokedCapability +export type BlobAllocate = InferInvokedCapability +export type BlobAccept = InferInvokedCapability +export type SpaceBlob = InferInvokedCapability +export type SpaceBlobAdd = InferInvokedCapability +export type SpaceBlobRemove = InferInvokedCapability< + typeof SpaceBlobCaps.remove +> +export type SpaceBlobList = InferInvokedCapability +export type SpaceBlobGet = InferInvokedCapability +export type W3sBlob = InferInvokedCapability +export type W3sBlobAllocate = InferInvokedCapability< + typeof W3sBlobCaps.allocate +> +export type W3sBlobAccept = InferInvokedCapability export interface BlobModel { digest: Multihash @@ -533,7 +549,7 @@ export interface BlobModel { } // Blob add -export interface BlobAddSuccess { +export interface SpaceBlobAddSuccess { site: UCANAwait<'.out.ok.site'> } @@ -546,39 +562,37 @@ export interface AwaitError extends Ucanto.Failure { } // TODO: We need Ucanto.Failure because provideAdvanced can't handle errors without it -export type BlobAddFailure = +export type SpaceBlobAddFailure = | BlobSizeOutsideOfSupportedRange | AwaitError | StorageGetError | Ucanto.Failure -export interface BlobListItem { +export interface BlobItem { blob: BlobModel + cause: Link insertedAt: ISO8601Date } // Blob remove -export interface BlobRemoveSuccess { +export interface SpaceBlobRemoveSuccess { size: number } // TODO: make types more specific -export type BlobRemoveFailure = Ucanto.Failure +export type SpaceBlobRemoveFailure = Ucanto.Failure // Blob list -export interface BlobListSuccess extends ListResponse {} +export interface SpaceBlobListSuccess extends ListResponse {} // TODO: make types more specific -export type BlobListFailure = Ucanto.Failure +export type SpaceBlobListFailure = Ucanto.Failure // Blob get -export interface BlobGetSuccess { - blob: { digest: Uint8Array; size: number } - cause: UnknownLink -} +export interface SpaceBlobGetSuccess extends BlobItem {} // TODO: make types more specific -export type BlobGetFailure = Ucanto.Failure +export type SpaceBlobGetFailure = Ucanto.Failure // Blob allocate export interface BlobAllocateSuccess { @@ -589,7 +603,7 @@ export interface BlobAllocateSuccess { export interface BlobAddress { url: ToString headers: Record - expiresAt: ISO8601Date + expires: number } // If user space has not enough space to allocate the blob. @@ -800,6 +814,7 @@ export interface AdminStoreInspectSuccess { } export type AdminStoreInspectFailure = Ucanto.Failure // Filecoin +export type Filecoin = InferInvokedCapability export type FilecoinOffer = InferInvokedCapability< typeof StorefrontCaps.filecoinOffer > @@ -889,6 +904,8 @@ export type ServiceAbilityArray = [ ProviderAdd['can'], Space['can'], SpaceInfo['can'], + SpaceContentServe['can'], + EgressRecord['can'], Upload['can'], UploadAdd['can'], UploadGet['can'], @@ -911,6 +928,7 @@ export type ServiceAbilityArray = [ RateLimitAdd['can'], RateLimitRemove['can'], RateLimitList['can'], + Filecoin['can'], FilecoinOffer['can'], FilecoinSubmit['can'], FilecoinAccept['can'], @@ -929,16 +947,19 @@ export type ServiceAbilityArray = [ Usage['can'], UsageReport['can'], Blob['can'], - BlobAdd['can'], - BlobRemove['can'], - BlobList['can'], - BlobGet['can'], - ServiceBlob['can'], BlobAllocate['can'], BlobAccept['can'], + SpaceBlob['can'], + SpaceBlobAdd['can'], + SpaceBlobRemove['can'], + SpaceBlobList['can'], + SpaceBlobGet['can'], + W3sBlob['can'], + W3sBlobAllocate['can'], + W3sBlobAccept['can'], HTTPPut['can'], - Index['can'], - IndexAdd['can'] + SpaceIndex['can'], + SpaceIndexAdd['can'] ] /** diff --git a/packages/capabilities/src/ucan.js b/packages/capabilities/src/ucan.js index 18e2dbb6e..a8765f236 100644 --- a/packages/capabilities/src/ucan.js +++ b/packages/capabilities/src/ucan.js @@ -111,10 +111,10 @@ export const conclude = capability({ * @example * ```js * { - iss: "did:web:web3.storage", + iss: "did:web:storacha.network", aud: "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi", att: [{ - "with": "did:web:web3.storage", + "with": "did:web:storacha.network", "can": "ucan/attest", "nb": { "proof": { @@ -129,7 +129,7 @@ export const conclude = capability({ */ export const attest = capability({ can: 'ucan/attest', - // Should be web3.storage DID + // Should be storacha.network DID with: Schema.did(), nb: Schema.struct({ // UCAN delegation that is being attested. diff --git a/packages/capabilities/src/upload.js b/packages/capabilities/src/upload.js index e35b5c631..78b52b896 100644 --- a/packages/capabilities/src/upload.js +++ b/packages/capabilities/src/upload.js @@ -3,7 +3,7 @@ * * These can be imported directly with: * ```js - * import * as Account from '@web3-storage/capabilities/upload' + * import * as Account from '@storacha/capabilities/upload' * ``` * * @module diff --git a/packages/capabilities/src/usage.js b/packages/capabilities/src/usage.js index bde471236..d80fb212d 100644 --- a/packages/capabilities/src/usage.js +++ b/packages/capabilities/src/usage.js @@ -40,20 +40,3 @@ export const report = capability({ ) }, }) - -/** - * Capability can be invoked by an agent to record usage data for a given resource. - */ -export const record = capability({ - can: 'usage/record', - with: SpaceDID, - nb: Schema.struct({ - /** CID of the resource that was served. */ - resource: Schema.link(), - /** Amount of bytes served. */ - bytes: Schema.integer().greaterThan(0), - /** Timestamp of the event in seconds after Unix epoch. */ - servedAt: Schema.integer().greaterThan(-1), - }), - derives: equalWith, -}) diff --git a/packages/capabilities/src/utils.js b/packages/capabilities/src/utils.js index 5360215e7..27108e908 100644 --- a/packages/capabilities/src/utils.js +++ b/packages/capabilities/src/utils.js @@ -1,10 +1,8 @@ +import * as API from '@ucanto/interface' import { DID, Schema, fail, ok } from '@ucanto/validator' -// eslint-disable-next-line no-unused-vars -import * as Types from '@ucanto/interface' - import { equals } from 'uint8arrays/equals' -// e.g. did:web:web3.storage or did:web:staging.web3.storage +// e.g. did:web:storacha.network or did:web:staging.storacha.network export const ProviderDID = DID.match({ method: 'web' }) export const SpaceDID = DID.match({ method: 'key' }) @@ -40,8 +38,8 @@ export function canDelegateURI(child, parent) { * Checks that `with` on claimed capability is the same as `with` * in delegated capability. Note this will ignore `can` field. * - * @param {Types.ParsedCapability} child - * @param {Types.ParsedCapability} parent + * @param {API.ParsedCapability} child + * @param {API.ParsedCapability} parent */ export function equalWith(child, parent) { return child.with === parent.with @@ -67,10 +65,10 @@ export function equal(child, parent, constraint) { } /** - * @template {Types.ParsedCapability<"store/add"|"store/get"|"store/remove", Types.URI<'did:'>, {link?: Types.Link}>} T + * @template {API.ParsedCapability<"store/add"|"store/get"|"store/remove", API.URI<'did:'>, {link?: API.Link}>} T * @param {T} claimed * @param {T} delegated - * @returns {Types.Result<{}, Types.Failure>} + * @returns {API.Result<{}, API.Failure>} */ export const equalLink = (claimed, delegated) => { if (claimed.with !== delegated.with) { @@ -92,10 +90,10 @@ export const equalLink = (claimed, delegated) => { } /** - * @template {Types.ParsedCapability<"space/blob/add"|"space/blob/remove"|"web3.storage/blob/allocate"|"web3.storage/blob/accept", Types.URI<'did:'>, {blob: { digest: Uint8Array, size: number }}>} T + * @template {API.ParsedCapability<"space/blob/add"|"space/blob/remove"|"web3.storage/blob/allocate"|"web3.storage/blob/accept"|"blob/allocate"|"blob/accept", API.URI<'did:'>, {blob: { digest: Uint8Array, size: number }}>} T * @param {T} claimed * @param {T} delegated - * @returns {Types.Result<{}, Types.Failure>} + * @returns {API.Result<{}, API.Failure>} */ export const equalBlob = (claimed, delegated) => { if (claimed.with !== delegated.with) { @@ -126,10 +124,10 @@ export const equalBlob = (claimed, delegated) => { } /** - * @template {Types.ParsedCapability<"http/put", Types.URI<'did:'>, {body: { digest: Uint8Array, size: number }}>} T + * @template {API.ParsedCapability<"http/put", API.URI<'did:'>, {body: { digest: Uint8Array, size: number }}>} T * @param {T} claimed * @param {T} delegated - * @returns {Types.Result<{}, Types.Failure>} + * @returns {API.Result<{}, API.Failure>} */ export const equalBody = (claimed, delegated) => { if (claimed.with !== delegated.with) { @@ -160,10 +158,10 @@ export const equalBody = (claimed, delegated) => { } /** - * @template {Types.ParsedCapability<"blob/add"|"blob/remove"|"blob/allocate"|"blob/accept"|"http/put", Types.URI<'did:'>, {content: Uint8Array}>} T + * @template {API.ParsedCapability<"blob/add"|"blob/remove"|"blob/allocate"|"blob/accept"|"http/put", API.URI<'did:'>, {content: Uint8Array}>} T * @param {T} claimed * @param {T} delegated - * @returns {Types.Result<{}, Types.Failure>} + * @returns {API.Result<{}, API.Failure>} */ export const equalContent = (claimed, delegated) => { if (claimed.with !== delegated.with) { @@ -185,12 +183,12 @@ export const equalContent = (claimed, delegated) => { } /** - * Checks that `claimed` {@link Types.Link} meets an `imposed` constraint. + * Checks that `claimed` {@link API.Link} meets an `imposed` constraint. * - * @param {Types.UnknownLink} claimed - * @param {Types.UnknownLink|undefined} imposed + * @param {API.UnknownLink} claimed + * @param {API.UnknownLink|undefined} imposed * @param {string} at - * @returns {Types.Result<{}, Types.Failure>} + * @returns {API.Result<{}, API.Failure>} */ export const checkLink = (claimed, imposed, at) => { return equal( @@ -202,8 +200,8 @@ export const checkLink = (claimed, imposed, at) => { /** * @template T - * @param {Types.Result} result - * @returns {{error: Types.Failure, ok?:undefined}|undefined} + * @param {API.Result} result + * @returns {{error: API.Failure, ok?:undefined}|undefined} */ export const and = (result) => (result.error ? result : undefined) diff --git a/packages/capabilities/src/web3.storage/blob.js b/packages/capabilities/src/web3.storage/blob.js index 42085380f..6303e1660 100644 --- a/packages/capabilities/src/web3.storage/blob.js +++ b/packages/capabilities/src/web3.storage/blob.js @@ -1,5 +1,5 @@ import { capability, Schema, Link, ok } from '@ucanto/validator' -import { content } from '../blob.js' +import { content } from '../space/blob.js' import { equalBlob, equalWith, @@ -17,6 +17,8 @@ import { * Capability can only be delegated (but not invoked) allowing audience to * derived any `web3.storage/blob/` prefixed capability for the (memory) space identified * by DID in the `with` field. + * + * @deprecated These capabilities were used by w3up to invoke on itself. */ export const blob = capability({ can: 'web3.storage/blob/*', @@ -31,6 +33,8 @@ export const blob = capability({ /** * `web3.storage/blob//allocate` capability can be invoked to create a memory * address where blob content can be written via HTTP PUT request. + * + * @deprecated These capabilities were used by w3up to invoke on itself. */ export const allocate = capability({ can: 'web3.storage/blob/allocate', @@ -67,6 +71,8 @@ export const allocate = capability({ * `blob/accept` capability invocation should either succeed when content is * delivered on allocated address or fail if no content is allocation expires * without content being delivered. + * + * @deprecated These capabilities were used by w3up to invoke on itself. */ export const accept = capability({ can: 'web3.storage/blob/accept', diff --git a/packages/capabilities/test/capabilities/access.test.js b/packages/capabilities/test/capabilities/access.test.js index af0d82d35..9253c4406 100644 --- a/packages/capabilities/test/capabilities/access.test.js +++ b/packages/capabilities/test/capabilities/access.test.js @@ -16,7 +16,7 @@ describe('access capabilities', function () { audience: service, with: agent.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }, }) @@ -33,7 +33,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/authorize') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }) } @@ -47,7 +47,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }, proofs: [ @@ -56,7 +56,7 @@ describe('access capabilities', function () { audience: agent2, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', }, }), ], @@ -75,7 +75,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/authorize') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }) } @@ -89,7 +89,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }, proofs: [ @@ -114,7 +114,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/authorize') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }) } @@ -128,7 +128,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }, proofs: [ @@ -153,7 +153,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/authorize') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }) } @@ -167,7 +167,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:ANOTHER_TEST', + iss: 'did:mailto:storacha.network:ANOTHER_TEST', att: [{ can: '*' }], }, proofs: [ @@ -176,7 +176,7 @@ describe('access capabilities', function () { audience: agent2, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', }, }), ], @@ -304,7 +304,7 @@ describe('access capabilities', function () { audience: service, with: alice.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', att: [{ can: '*' }], }, proofs: [ @@ -338,11 +338,11 @@ describe('access capabilities', function () { with: bob.did(), nb: { // @ts-expect-error - iss: 'did:NOT_MAILTO:web3.storage:test', + iss: 'did:NOT_MAILTO:storacha.network:test', att: [{ can: '*' }], }, }) - }, /Expected a did:mailto: but got "did:NOT_MAILTO:web3.storage:test" instead/) + }, /Expected a did:mailto: but got "did:NOT_MAILTO:storacha.network:test" instead/) }) }) @@ -354,7 +354,7 @@ describe('access capabilities', function () { audience: service, with: agent.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -373,7 +373,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/confirm') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -389,7 +389,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -400,7 +400,7 @@ describe('access capabilities', function () { audience: agent2, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', }, }), ], @@ -419,7 +419,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/confirm') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -435,7 +435,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -462,7 +462,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/confirm') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -478,7 +478,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -505,7 +505,7 @@ describe('access capabilities', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'access/confirm') assert.deepEqual(result.ok.capability.nb, { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -521,7 +521,7 @@ describe('access capabilities', function () { audience: service, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:ANOTHER_TEST', + iss: 'did:mailto:storacha.network:ANOTHER_TEST', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -532,7 +532,7 @@ describe('access capabilities', function () { audience: agent2, with: agent1.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', }, }), ], @@ -666,7 +666,7 @@ describe('access capabilities', function () { audience: service, with: alice.did(), nb: { - iss: 'did:mailto:web3.storage:test', + iss: 'did:mailto:storacha.network:test', aud: agent2.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), @@ -702,20 +702,20 @@ describe('access capabilities', function () { with: bob.did(), nb: { // @ts-expect-error - iss: 'did:NOT_MAILTO:web3.storage:test', + iss: 'did:NOT_MAILTO:storacha.network:test', aud: bob.did(), att: [{ can: '*' }], cause: parseLink('bafkqaaa'), }, }) - }, /Expected a did:mailto: but got "did:NOT_MAILTO:web3.storage:test" instead/) + }, /Expected a did:mailto: but got "did:NOT_MAILTO:storacha.network:test" instead/) }) }) describe('access/claim', () => { // ensure we can use the capability to produce the invocations from the spec at https://github.com/web3-storage/specs/blob/576b988fb7cfa60049611963179277c420605842/w3-access.md it('can create/access delegations from spec', async () => { - const audience = service.withDID('did:web:web3.storage') + const audience = service.withDID('did:web:storacha.network') const examples = [ // https://github.com/web3-storage/specs/blob/576b988fb7cfa60049611963179277c420605842/w3-access.md#accessclaim diff --git a/packages/capabilities/test/capabilities/blob.test.js b/packages/capabilities/test/capabilities/blob.test.js new file mode 100644 index 000000000..26cdbb3b9 --- /dev/null +++ b/packages/capabilities/test/capabilities/blob.test.js @@ -0,0 +1,316 @@ +import assert from 'assert' +import { access } from '@ucanto/validator' +import { ed25519, Verifier } from '@ucanto/principal' +import * as DID from '@ipld/dag-ucan/did' +import * as Blob from '../../src/blob.js' +import * as Capability from '../../src/top.js' +import { + alice, + service as storageNode, + mallory as account, + bob, +} from '../helpers/fixtures.js' +import { + createCar, + createCborCid, + validateAuthorization, +} from '../helpers/utils.js' + +const top = () => + Capability.top.delegate({ + issuer: account, + audience: alice, + with: account.did(), + }) + +const blob = async () => + Blob.blob.delegate({ + issuer: account, + audience: alice, + with: account.did(), + proofs: [await top()], + }) + +describe('blob capabilities', function () { + it('blob/allocate can be derived from *', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const allocate = Blob.allocate.invoke({ + issuer: alice, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + cause: await createCborCid({ now: Date.now() }), + }, + proofs: [await top()], + }) + + const result = await access(await allocate.delegate(), { + capability: Blob.allocate, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.allocate.can) + }) + + it('blob/allocate can be derived from blob/*', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const allocate = Blob.allocate.invoke({ + issuer: alice, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + cause: await createCborCid({ now: Date.now() }), + }, + proofs: [await blob()], + }) + + const result = await access(await allocate.delegate(), { + capability: Blob.allocate, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.allocate.can) + }) + + it('blob/allocate can be derived from blob/* derived from *', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const blob = await Blob.blob.delegate({ + issuer: alice, + audience: bob, + with: account.did(), + proofs: [await top()], + }) + + const allocate = Blob.allocate.invoke({ + issuer: bob, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + cause: await createCborCid({ now: Date.now() }), + }, + proofs: [blob], + }) + + const result = await access(await allocate.delegate(), { + capability: Blob.allocate, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.allocate.can) + }) + + it('blob/allocate should fail when escalating space constraint', async () => { + const space0 = await ed25519.generate() + const space1 = await ed25519.generate() + const car = await createCar('test') + + const blob = await Blob.allocate.delegate({ + issuer: alice, + audience: bob, + with: account.did(), + nb: { + space: DID.parse(space0.did()), + }, + proofs: [await top()], + }) + + const allocate = Blob.allocate.invoke({ + issuer: bob, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space1.did()), + cause: await createCborCid({ now: Date.now() }), + }, + proofs: [blob], + }) + + const result = await access(await allocate.delegate(), { + capability: Blob.allocate, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.error) + assert(result.error.message.includes('violates imposed space constraint')) + }) + + it('blob/accept can be derived from *', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const accept = Blob.accept.invoke({ + issuer: alice, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + _put: { + 'ucan/await': ['.out.ok', await createCborCid('receipt')], + }, + }, + proofs: [await top()], + }) + + const result = await access(await accept.delegate(), { + capability: Blob.accept, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.accept.can) + }) + + it('blob/accept can be derived from blob/*', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const accept = Blob.accept.invoke({ + issuer: alice, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + _put: { + 'ucan/await': ['.out.ok', await createCborCid('receipt')], + }, + }, + proofs: [await blob()], + }) + + const result = await access(await accept.delegate(), { + capability: Blob.accept, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.accept.can) + }) + + it('blob/accept can be derived from blob/* derived from *', async () => { + const space = await ed25519.generate() + const car = await createCar('test') + + const blob = await Blob.blob.delegate({ + issuer: alice, + audience: bob, + with: account.did(), + proofs: [await top()], + }) + + const accept = Blob.accept.invoke({ + issuer: bob, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space.did()), + _put: { + 'ucan/await': ['.out.ok', await createCborCid('receipt')], + }, + }, + proofs: [blob], + }) + + const result = await access(await accept.delegate(), { + capability: Blob.accept, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.ok) + assert.deepEqual(result.ok.audience.did(), storageNode.did()) + assert.equal(result.ok.capability.can, Blob.accept.can) + }) + + it('blob/accept should fail when escalating space constraint', async () => { + const space0 = await ed25519.generate() + const space1 = await ed25519.generate() + const car = await createCar('test') + + const blob = await Blob.accept.delegate({ + issuer: alice, + audience: bob, + with: account.did(), + nb: { + space: DID.parse(space0.did()), + }, + proofs: [await top()], + }) + + const accept = Blob.accept.invoke({ + issuer: bob, + audience: storageNode, + with: account.did(), + nb: { + blob: { + digest: car.cid.multihash.bytes, + size: car.bytes.length, + }, + space: DID.parse(space1.did()), + _put: { + 'ucan/await': ['.out.ok', await createCborCid('receipt')], + }, + }, + proofs: [blob], + }) + + const result = await access(await accept.delegate(), { + capability: Blob.accept, + principal: Verifier, + authority: storageNode, + validateAuthorization, + }) + assert.ok(result.error) + assert(result.error.message.includes('violates imposed space constraint')) + }) +}) diff --git a/packages/capabilities/test/capabilities/index.test.js b/packages/capabilities/test/capabilities/index.test.js index cafd31a64..e350b13f7 100644 --- a/packages/capabilities/test/capabilities/index.test.js +++ b/packages/capabilities/test/capabilities/index.test.js @@ -1,7 +1,7 @@ import assert from 'assert' import { access } from '@ucanto/validator' import { Verifier } from '@ucanto/principal' -import * as Index from '../../src/index/index.js' +import * as SpaceIndex from '../../src/space/index.js' import * as Capability from '../../src/top.js' import { alice, @@ -19,7 +19,7 @@ const top = async () => }) const index = async () => - Index.index.delegate({ + SpaceIndex.index.delegate({ issuer: account, audience: alice, with: account.did(), @@ -28,7 +28,7 @@ const index = async () => describe('index capabilities', function () { it('space/index/add can be derived from *', async () => { - const add = Index.add.invoke({ + const add = SpaceIndex.add.invoke({ issuer: alice, audience: w3, with: account.did(), @@ -39,7 +39,7 @@ describe('index capabilities', function () { }) const result = await access(await add.delegate(), { - capability: Index.add, + capability: SpaceIndex.add, principal: Verifier, authority: w3, validateAuthorization, @@ -57,7 +57,7 @@ describe('index capabilities', function () { }) it('space/index/add can be derived from index/*', async () => { - const add = Index.add.invoke({ + const add = SpaceIndex.add.invoke({ issuer: alice, audience: w3, with: account.did(), @@ -68,7 +68,7 @@ describe('index capabilities', function () { }) const result = await access(await add.delegate(), { - capability: Index.add, + capability: SpaceIndex.add, principal: Verifier, authority: w3, validateAuthorization, @@ -86,14 +86,14 @@ describe('index capabilities', function () { }) it('space/index/add can be derived from index/* derived from *', async () => { - const index = await Index.index.delegate({ + const index = await SpaceIndex.index.delegate({ issuer: alice, audience: bob, with: account.did(), proofs: [await top()], }) - const add = Index.add.invoke({ + const add = SpaceIndex.add.invoke({ issuer: bob, audience: w3, with: account.did(), @@ -104,7 +104,7 @@ describe('index capabilities', function () { }) const result = await access(await add.delegate(), { - capability: Index.add, + capability: SpaceIndex.add, principal: Verifier, authority: w3, validateAuthorization, @@ -122,7 +122,7 @@ describe('index capabilities', function () { }) it('space/index/add should fail when escalating index constraint', async () => { - const delegation = await Index.add.delegate({ + const delegation = await SpaceIndex.add.delegate({ issuer: alice, audience: bob, with: account.did(), @@ -132,7 +132,7 @@ describe('index capabilities', function () { proofs: [await top()], }) - const add = Index.add.invoke({ + const add = SpaceIndex.add.invoke({ issuer: bob, audience: w3, with: account.did(), @@ -143,7 +143,7 @@ describe('index capabilities', function () { }) const result = await access(await add.delegate(), { - capability: Index.add, + capability: SpaceIndex.add, principal: Verifier, authority: w3, validateAuthorization, diff --git a/packages/capabilities/test/capabilities/plan.test.js b/packages/capabilities/test/capabilities/plan.test.js index e255d8f17..a885e2ccc 100644 --- a/packages/capabilities/test/capabilities/plan.test.js +++ b/packages/capabilities/test/capabilities/plan.test.js @@ -104,7 +104,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: await createAuthorization({ agent, service, account }), }) @@ -130,7 +130,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, }) @@ -150,7 +150,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: await createAuthorization({ agent, service, account }), }) @@ -170,7 +170,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: [ await Plan.set.delegate({ @@ -202,7 +202,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: [ await Plan.set.delegate({ @@ -210,7 +210,7 @@ describe('plan/set', function () { audience: bob, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: await createAuthorization({ agent, service, account }), }), @@ -237,7 +237,7 @@ describe('plan/set', function () { audience: service, with: account, nb: { - product: 'did:web:lite.web3.storage', + product: 'did:web:lite.storacha.network', }, proofs: [ await Plan.set.delegate({ @@ -245,7 +245,7 @@ describe('plan/set', function () { audience: bob, with: account, nb: { - product: 'did:web:starter.web3.storage', + product: 'did:web:starter.storacha.network', }, proofs: await createAuthorization({ agent, service, account }), }), diff --git a/packages/capabilities/test/capabilities/provider.test.js b/packages/capabilities/test/capabilities/provider.test.js index ab0afcac7..2d566bf64 100644 --- a/packages/capabilities/test/capabilities/provider.test.js +++ b/packages/capabilities/test/capabilities/provider.test.js @@ -18,7 +18,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: await createAuthorization({ agent, service, account }), @@ -36,7 +36,7 @@ describe('provider/add', function () { assert.deepEqual(result.ok.audience.did(), service.did()) assert.equal(result.ok.capability.can, 'provider/add') assert.deepEqual(result.ok.capability.nb, { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }) } @@ -51,7 +51,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, }) @@ -80,7 +80,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: [delegation], @@ -110,7 +110,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: [attestation], @@ -135,7 +135,7 @@ describe('provider/add', function () { with: bobAccount.did(), // @ts-ignore nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', }, }) }, /Error: Invalid 'nb' - Object contains invalid field "consumer"/) @@ -149,9 +149,9 @@ describe('provider/add', function () { audience: service, with: bobAccount.did(), nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', // @ts-expect-error - consumer: 'did:mailto:web3.storage:user', + consumer: 'did:mailto:storacha.network:user', }, }) }, /Error: Invalid 'nb' - Object contains invalid field "consumer"/) @@ -166,7 +166,7 @@ describe('provider/add', function () { with: bobAccount.did(), // @ts-expect-error - missing provider nb: { - // provider: 'did:web:test.web3.storage', + // provider: 'did:web:test.upload.storacha.network', consumer: bob.did(), }, }) @@ -181,7 +181,7 @@ describe('provider/add', function () { audience: service, with: bobAccount.did(), nb: { - provider: 'did:web:web3.storage:providers:w3up-beta', + provider: 'did:web:storacha.network:providers:w3up-beta', consumer: bob.did(), }, }) @@ -197,7 +197,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: [ @@ -206,7 +206,7 @@ describe('provider/add', function () { audience: bob, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: await createAuthorization({ agent, service, account }), @@ -233,7 +233,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: [ @@ -242,7 +242,7 @@ describe('provider/add', function () { audience: bob, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', }, proofs: await createAuthorization({ agent, service, account }), }), @@ -268,7 +268,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: space.did(), }, proofs: [ @@ -303,7 +303,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: bob.did(), }, proofs: [ @@ -338,7 +338,7 @@ describe('provider/add', function () { audience: service, with: account, nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: bob.did(), }, proofs: [ @@ -350,7 +350,7 @@ describe('provider/add', function () { with: account, can: 'provider/add', nb: { - provider: 'did:web:web3.storage:providers:w3up-beta', + provider: 'did:web:storacha.network:providers:w3up-beta', consumer: space.did(), }, }, @@ -379,7 +379,7 @@ describe('provider/add', function () { audience: service, with: 'did:mailto:mallory.com:bob', nb: { - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', consumer: bob.did(), }, proofs: [ @@ -391,7 +391,7 @@ describe('provider/add', function () { with: account, can: 'provider/add', nb: { - provider: 'did:web:web3.storage:providers:w3up-beta', + provider: 'did:web:storacha.network:providers:w3up-beta', consumer: space.did(), }, }, @@ -428,7 +428,7 @@ describe('provider/add', function () { with: account.did(), nb: { consumer: space.did(), - provider: 'did:web:test.web3.storage', + provider: 'did:web:test.upload.storacha.network', }, // NOTE: no proofs! }) diff --git a/packages/capabilities/test/helpers/fixtures.js b/packages/capabilities/test/helpers/fixtures.js index a4ae2d1b4..11bbd15b3 100644 --- a/packages/capabilities/test/helpers/fixtures.js +++ b/packages/capabilities/test/helpers/fixtures.js @@ -8,7 +8,7 @@ export const alice = Signer.parse( ) export const aliceAccount = Absentee.from({ - id: 'did:mailto:test.web3.storage:alice', + id: 'did:mailto:test.storacha.network:alice', }) /** did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob */ @@ -17,7 +17,7 @@ export const bob = Signer.parse( ) export const bobAccount = Absentee.from({ - id: 'did:mailto:test.web3.storage:bob', + id: 'did:mailto:test.storacha.network:bob', }) /** did:key:z6MktafZTREjJkvV5mfJxcLpNBoVPwDLhTuMg9ng7dY4zMAL */ @@ -26,13 +26,22 @@ export const mallory = Signer.parse( ) export const malloryAccount = Absentee.from({ - id: 'did:mailto:test.web3.storage:mallory', + id: 'did:mailto:test.storacha.network:mallory', }) export const service = Signer.parse( 'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8=' -).withDID('did:web:test.web3.storage') +).withDID('did:web:test.upload.storacha.network') export const readmeCID = parseLink( 'bafybeihqfdg2ereoijjoyrqzr2x2wsasqm2udurforw7pa3tvbnxhojao4' ) + +export const gateway = Signer.parse( + 'MgCaNpGXCEX0+BxxE4SjSStrxU9Ru/Im+HGNQ/JJx3lDoI+0B3NWjWW3G8OzjbazZjanjM3kgfcZbvpyxv20jHtmcTtg=' // random key +).withDID('did:web:w3s.link') + +/** did:key:z6MktYxTNoCxrXhK9oS5PdzutujTJ5DaS3FWYxNpRTXwrH6h */ +export const space = Signer.parse( + 'MgCYBaaeyfAHFNt5+M07rY9pPLnmhyxvMEj5jdyAN0ajSlO0B0Xk2fW+t/EsB2nqWraDmB7N0NiTXKZaVBbOpCMtCktI=' // random key +) diff --git a/packages/capabilities/test/helpers/utils.js b/packages/capabilities/test/helpers/utils.js index 980e64c8e..92b0758d4 100644 --- a/packages/capabilities/test/helpers/utils.js +++ b/packages/capabilities/test/helpers/utils.js @@ -23,9 +23,16 @@ export async function createCborCid(data) { /** * @param {string} source */ -export async function createCarCid(source) { +export async function createCar(source) { const cbor = await CBOR.write({ hello: source }) - const shard = await CAR.codec.write({ roots: [cbor] }) + return await CAR.codec.write({ roots: [cbor] }) +} + +/** + * @param {string} source + */ +export async function createCarCid(source) { + const shard = await createCar(source) return shard.cid } diff --git a/packages/cli/.gitattributes b/packages/cli/.gitattributes new file mode 100644 index 000000000..55b172c5d --- /dev/null +++ b/packages/cli/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +*.car -text diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/packages/cli/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md new file mode 100644 index 000000000..4c77ee819 --- /dev/null +++ b/packages/cli/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog + +## [1.1.1](https://github.com/storacha/upload-service/compare/cli-v1.1.0...cli-v1.1.1) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.1.0](https://github.com/storacha/upload-service/compare/cli-v1.0.1...cli-v1.1.0) (2024-12-19) + + +### Features + +* content serve authorization ([#1590](https://github.com/storacha/upload-service/issues/1590)) + set default gateway ([#99](https://github.com/storacha/upload-service/issues/99)) ([6cbb202](https://github.com/storacha/upload-service/commit/6cbb2027c829189937363b374e258bb1a2b07722)) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/cli-v1.0.0...cli-v1.0.1) (2024-11-13) + + +### Fixes + +* trigger release ([f0f9a56](https://github.com/storacha/upload-service/commit/f0f9a56bb28bc50e33845f07c859cd209562a338)) + + +### Other Changes + +* format ([f740119](https://github.com/storacha/upload-service/commit/f74011982962d0c4e0b70b235d146cd611b8ea77)) + +## 1.0.0 (2024-11-12) + + +### Fixes + +* trigger release ([3fc3fc2](https://github.com/storacha/upload-service/commit/3fc3fc24f3d4b813249b714a23bbe4f69011ab76)) diff --git a/packages/cli/LICENSE.md b/packages/cli/LICENSE.md new file mode 100644 index 000000000..5662b2641 --- /dev/null +++ b/packages/cli/LICENSE.md @@ -0,0 +1,232 @@ +The contents of this repository are Copyright (c) corresponding authors and +contributors, licensed under the `Permissive License Stack` meaning either of: + +- Apache-2.0 Software License: https://www.apache.org/licenses/LICENSE-2.0 + ([...4tr2kfsq](https://dweb.link/ipfs/bafkreiankqxazcae4onkp436wag2lj3ccso4nawxqkkfckd6cg4tr2kfsq)) + +- MIT Software License: https://opensource.org/licenses/MIT + ([...vljevcba](https://dweb.link/ipfs/bafkreiepofszg4gfe2gzuhojmksgemsub2h4uy2gewdnr35kswvljevcba)) + +You may not use the contents of this repository except in compliance +with one of the listed Licenses. For an extended clarification of the +intent behind the choice of Licensing please refer to +https://protocol.ai/blog/announcing-the-permissive-license-stack/ + +Unless required by applicable law or agreed to in writing, software +distributed under the terms listed in this notice is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +either express or implied. See each License for the specific language +governing permissions and limitations under that License. + + + +`SPDX-License-Identifier: Apache-2.0 OR MIT` + +Verbatim copies of both licenses are included below: + +
Apache-2.0 Software License + +``` + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS +``` + +
+ +
MIT Software License + +``` +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +``` + +
\ No newline at end of file diff --git a/packages/cli/README.md b/packages/cli/README.md new file mode 100644 index 000000000..22f4aa534 --- /dev/null +++ b/packages/cli/README.md @@ -0,0 +1,308 @@ +# CLI + +The command line interface to the Storacha Network. + +## Getting started + +Install the CLI from npm (**requires Node 18 or higher**): + +```sh +npm install -g @storacha/cli +``` + +Login with this agent to act on behalf of the account associated with your email address: + +```sh +storacha login alice@example.com +``` + +Create a new Space for storing your data and register it: + +```sh +storacha space create Documents # pick a good name! +``` + +If you'd like to learn more about what is going on under the hood with w3up and its use of Spaces, [UCANs](https://ucan.xyz/), and more, check out the `client` README [here](https://github.com/storacha/upload-service/tree/main/packages/w3up-client#usage). + +Upload a file or directory: + +```sh +storacha up recipies.txt +``` + +> ⚠️❗ **Public Data** 🌎: All data uploaded to storacha is available to anyone who requests it using the correct CID. Do not store any private or sensitive information in an unencrypted form using storacha. + +> ⚠️❗ **Permanent Data** ♾️: Removing files from storacha will remove them from the file listing for your account, but that doesn’t prevent nodes on the decentralized storage network from retaining copies of the data indefinitely. Do not use storacha for data that may need to be permanently deleted in the future. + +## Commands + +- Basics + - [`storacha login`](#storacha-login-email) + - [`storacha up`](#storacha-up-path-path) + - [`storacha ls`](#storacha-ls) + - [`storacha rm`](#storacha-rm-root-cid) + - [`storacha open`](#storacha-open-cid) + - [`storacha whoami`](#storacha-whoami) +- Space management + - [`storacha space add`](#storacha-space-add-proofucan) + - [`storacha space create`](#storacha-space-create-name) + - [`storacha space ls`](#storacha-space-ls) + - [`storacha space use`](#storacha-space-use-did) + - [`storacha space info`](#storacha-space-info) +- Capability management + - [`storacha delegation create`](#storacha-delegation-create-audience-did) + - [`storacha delegation ls`](#storacha-delegation-ls) + - [`storacha delegation revoke`](#storacha-delegation-revoke-delegation-cid) + - [`storacha proof add`](#storacha-proof-add-proofucan) + - [`storacha proof ls`](#storacha-proof-ls) +- Key management + - [`storacha key create`](#storacha-key-create) +- UCAN-HTTP Bridge + - [`storacha bridge generate-tokens`](#storacha-bridge-generate-tokens) +- Advanced usage + - [`storacha can blob add`](#storacha-can-blob-add-path) + - [`storacha can blob ls`](#storacha-can-blob-ls) + - [`storacha can blob rm`](#storacha-can-blob-rm-multihash) + - [`storacha can index add`](#storacha-can-index-add-cid) + - [`storacha can space info`](#storacha-can-space-info-did) coming soon! + - [`storacha can space recover`](#storacha-can-space-recover-email) coming soon! + - [`storacha can upload add`](#storacha-can-upload-add-root-cid-shard-cid-shard-cid) + - [`storacha can upload ls`](#storacha-can-upload-ls) + - [`storacha can upload rm`](#storacha-can-upload-rm-root-cid) + +--- + +### `storacha login ` + +Authenticate this agent with your email address to get access to all capabilities that had been delegated to it. + +### `storacha up [path...]` + +Upload file(s) to web3.storage. The IPFS Content ID (CID) for your files is calculated on your machine, and sent up along with your files. web3.storage makes your content available on the IPFS network + +- `--no-wrap` Don't wrap input files with a directory. +- `-H, --hidden` Include paths that start with ".". +- `-c, --car` File is a CAR file. +- `--shard-size` Shard uploads into CAR files of approximately this size in bytes. +- `--concurrent-requests` Send up to this many CAR shards concurrently. + +### `storacha ls` + +List all the uploads registered in the current space. + +- `--json` Format as newline delimited JSON +- `--shards` Pretty print with shards in output + +### `storacha rm ` + +Remove an upload from the uploads listing. Note that this command does not remove the data from the IPFS network, nor does it remove it from space storage (by default). + +- `--shards` Also remove all shards referenced by the upload from the store. Use with caution and ensure other uploads do not reference the same shards. + +### `storacha open ` + +Open a CID on https://w3s.link in your browser. You can also pass a CID and a path. + +```bash +# opens a browser to https://w3s.link/ipfs/bafybeidluj5ub7okodgg5v6l4x3nytpivvcouuxgzuioa6vodg3xt2uqle +storacha open bafybeidluj5ub7okodgg5v6l4x3nytpivvcouuxgzuioa6vodg3xt2uqle + +# opens a browser to https://w3s.link/ipfs/bafybeidluj5ub7okodgg5v6l4x3nytpivvcouuxgzuioa6vodg3xt2uqle/olizilla.png +storacha open bafybeidluj5ub7okodgg5v6l4x3nytpivvcouuxgzuioa6vodg3xt2uqle/olizilla.png +``` + +### `storacha whoami` + +Print information about the current agent. + +### `storacha space add ` + +Add a space to the agent. The proof is a CAR encoded UCAN delegating capabilities over a space to _this_ agent. + +`proof` is a filesystem path to a CAR encoded UCAN, as generated by `storacha delegation create` _or_ a base64 identity CID string as created by `storacha delegation create --base64`. + +### `storacha space create [name]` + +Create a new space with an optional name. + +### `storacha space ls` + +List spaces known to the agent. + +### `storacha space use ` + +Set the current space in use by the agent. + +### `storacha space info` + +Get information about a space (by default the current space) from the service, including +which providers the space is currently registered with. + +- `--space` The space to get information about. Defaults to the current space. +- `--json` Format as newline delimited JSON + +### `storacha delegation create ` + +Create a delegation to the passed audience for the given abilities with the _current_ space as the resource. + +- `--can` A capability to delegate. To specify more than one capability, use this option more than once. +- `--name` Human readable name for the audience receiving the delegation. +- `--type` Type of the audience receiving the delegation, one of: device, app, service. +- `--output` Path of file to write the exported delegation data to. +- `--base64` Format as base64 identity CID string. Useful when saving it as an environment variable. + +```bash +# delegate space/info to did:key:z6M..., output as a CAR +storacha delegation create did:key:z6M... --can space/info --output ./info.ucan + +# delegate admin capabilities to did:key:z6M..., output as a string +storacha delegation create did:key:z6M... --can 'space/*' --can 'upload/*' --can 'filecoin/*' --base64 + +# delegate write (not remove) capabilities to did:key:z6M..., output as a string +storacha delegation create did:key:z6M... \ + --can 'space/blob/add' \ + --can 'space/index/add' \ + --can 'upload/add' \ + --can 'filecoin/offer' \ + --base64 +``` + +### `storacha delegation ls` + +List delegations created by this agent for others. + +- `--json` Format as newline delimited JSON + +### `storacha delegation revoke ` + +Revoke a delegation by CID. + +- `--proof` Name of a file containing the delegation and any additional proofs needed to prove authority to revoke + +### `storacha proof add ` + +Add a proof delegated to this agent. The proof is a CAR encoded delegation to _this_ agent. Note: you probably want to use `storacha space add` unless you know the delegation you received targets a resource _other_ than a space. + +### `storacha proof ls` + +List proofs of delegated capabilities. Proofs are delegations with an audience matching the agent DID. + +- `--json` Format as newline delimited JSON + +### `storacha key create` + +Print a new key pair. Does not change your current signing key + +- `--json` Export as dag-json + +### `storacha bridge generate-tokens` + +Generate tokens that can be used as the `X-Auth-Secret` and `Authorization` headers required to use the UCAN-HTTP bridge. + +See the [UCAN Bridge specification](https://github.com/storacha/specs/blob/main/w3-ucan-bridge.md) for more information +on how these are expected to be used. + +- `--can` One or more abilities to delegate. +- `--expiration` Unix timestamp (in seconds) when the delegation is no longer valid. Zero indicates no expiration. +- `--json` If set, output JSON suitable to splat into the `headers` field of a `fetch` request. + +### `storacha can blob add [path]` + +Store a blob file to the service. + +### `storacha can blob ls` + +List blobs in the current space. + +- `--json` Format as newline delimited JSON +- `--size` The desired number of results to return +- `--cursor` An opaque string included in a prior upload/list response that allows the service to provide the next "page" of results + +### `storacha can blob rm ` + +Remove a blob from the store by base58btc encoded multihash. + +### `storacha can space info ` + +### `storacha can space recover ` + +### `storacha can upload add [shard-cid...]` + +Register an upload - a DAG with the given root data CID that is stored in the given shard(s), identified by CID. + +### `storacha can upload ls` + +List uploads in the current space. + +- `--json` Format as newline delimited JSON +- `--shards` Pretty print with shards in output +- `--size` The desired number of results to return +- `--cursor` An opaque string included in a prior upload/list response that allows the service to provide the next "page" of results +- `--pre` If true, return the page of results preceding the cursor + +### `storacha can upload rm ` + +Remove an upload from the current space's upload list. Does not remove blobs from the store. + +## Environment Variables + +### `STORACHA_PRINCIPAL` + +Set the key `storacha` CLI should use to sign ucan invocations. By default `storacha` CLI will generate a new Ed25519 key on first run and store it. Set it along with a custom `STORACHA_STORE_NAME` to manage multiple custom keys and profiles. Trying to use an existing store with different keys will fail. + +You can generate Ed25519 keys with `storacha key create`. + +**Usage** + +```bash +STORACHA_PRINCIPAL=$(storacha key create --json | jq -r .key) STORACHA_STORE_NAME="other" storacha whoami +did:key:z6Mkf7bvSNgoXk67Ubhie8QMurN9E4yaCCGBzXow78zxnmuB +``` + +Default _unset_, a random Ed25519 key is generated. + +### `STORACHA_STORE_NAME` + +Allows you to use the `storacha` CLI with different profiles. You could use it to log in with different emails and keep the delegations separate. + +`storacha` CLI stores state to disk using the [`conf`](https://github.com/sindresorhus/conf) module. `STORACHA_STORE_NAME` sets the conf [`configName`](https://github.com/sindresorhus/conf#configname) option. + +Default `storacha-cli` + +### `STORACHA_SERVICE_URL` + +`storacha` CLI will use the w3up service at https://upload.storacha.network. If you would like +to use a different w3up-compatible service, set `STORACHA_SERVICE_DID` and `STORACHA_SERVICE_URL` environment variables to set the service DID and URL endpoint. + +Default `https://upload.storacha.network` + +### `STORACHA_SERVICE_DID` + +`storacha` CLI will use the w3up `did:web:upload.storacha.network` as the service DID. If you would like +to use a different w3up-compatible service, set `STORACHA_SERVICE_DID` and `STORACHA_SERVICE_URL` environment variables to set the service DID and URL endpoint. + +Default `did:web:upload.storacha.network` + +### `STORACHA_RECEIPTS_URL` + +The URL at which UCAN receipts issued by the service may be fetched. + +Default `https://upload.storacha.network/receipt/` + +## FAQ + +### Where are my keys and delegations stored? + +In the system default user config directory: + +- macOS: `~/Library/Preferences/storacha` +- Windows: `%APPDATA%\storacha\Config` (for example, `C:\Users\USERNAME\AppData\Roaming\storacha\Config`) +- Linux: `~/.config/storacha` (or `$XDG_CONFIG_HOME/storacha`) + +## Contributing + +Feel free to join in. All welcome. Please read our [contributing guidelines](https://github.com/storacha/upload-service/blob/main/CONTRIBUTING.md) and/or [open an issue](https://github.com/storacha/upload-service/issues)! + +## License + +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/LICENSE.md) diff --git a/packages/cli/account.js b/packages/cli/account.js new file mode 100644 index 000000000..2f19848b0 --- /dev/null +++ b/packages/cli/account.js @@ -0,0 +1,58 @@ +import * as Account from '@storacha/client/account' +import * as Result from '@storacha/client/result' +import * as DidMailto from '@storacha/did-mailto' +import { getClient } from './lib.js' +import ora from 'ora' + +/** + * @typedef {Awaited>['ok']&{}} View + */ + +/** + * @param {DidMailto.EmailAddress} email + */ +export const login = async (email) => loginWithClient(email, await getClient()) + +/** + * @param {DidMailto.EmailAddress} email + * @param {import('@storacha/client').Client} client + * @returns {Promise} + */ +export const loginWithClient = async (email, client) => { + /** @type {import('ora').Ora|undefined} */ + let spinner + const timeout = setTimeout(() => { + spinner = ora( + `🔗 please click the link sent to ${email} to authorize this agent` + ).start() + }, 1000) + try { + const account = Result.try(await Account.login(client, email)) + + Result.try(await account.save()) + + if (spinner) spinner.stop() + console.log(`⁂ Agent was authorized by ${account.did()}`) + return account + } catch (err) { + if (spinner) spinner.stop() + console.error(err) + process.exit(1) + } finally { + clearTimeout(timeout) + } +} + +export const list = async () => { + const client = await getClient() + const accounts = Object.values(Account.list(client)) + for (const account of accounts) { + console.log(account.did()) + } + + if (accounts.length === 0) { + console.log( + '⁂ Agent has not been authorized yet. Try `storacha login` to authorize this agent with your account.' + ) + } +} diff --git a/packages/cli/api.js b/packages/cli/api.js new file mode 100644 index 000000000..336ce12bb --- /dev/null +++ b/packages/cli/api.js @@ -0,0 +1 @@ +export {} diff --git a/packages/cli/api.ts b/packages/cli/api.ts new file mode 100644 index 000000000..d83f73948 --- /dev/null +++ b/packages/cli/api.ts @@ -0,0 +1 @@ +export * from '@ucanto/interface' diff --git a/packages/cli/bin.js b/packages/cli/bin.js new file mode 100755 index 000000000..e68972cec --- /dev/null +++ b/packages/cli/bin.js @@ -0,0 +1,386 @@ +#!/usr/bin/env node + +import sade from 'sade' +import open from 'open' +import updateNotifier from 'update-notifier' +import { getPkg } from './lib.js' +import { + Account, + Space, + Coupon, + Bridge, + accessClaim, + addSpace, + listSpaces, + useSpace, + spaceInfo, + createDelegation, + listDelegations, + revokeDelegation, + addProof, + listProofs, + upload, + remove, + list, + whoami, + usageReport, + getPlan, + createKey, + reset, +} from './index.js' +import { + blobAdd, + blobList, + blobRemove, + indexAdd, + uploadAdd, + uploadList, + uploadRemove, + filecoinInfo, +} from './can.js' + +const pkg = getPkg() + +updateNotifier({ pkg }).notify({ isGlobal: true }) + +const cli = sade('storacha') + +cli + .version(pkg.version) + .example('login user@example.com') + .example('up path/to/files') + +cli + .command('login ') + .example('login user@example.com') + .describe( + 'Authenticate this agent with your email address to gain access to all capabilities that have been delegated to it.' + ) + .action(Account.login) + +cli + .command('plan get [email]') + .example('plan get user@example.com') + .describe('Displays plan given account is on') + .action(getPlan) + +cli + .command('account ls') + .alias('account list') + .describe('List accounts this agent has been authorized to act on behalf of.') + .action(Account.list) + +cli + .command('up [file]') + .alias('upload', 'put') + .describe('Store a file(s) to the service and register an upload.') + .option('-H, --hidden', 'Include paths that start with ".".', false) + .option('-c, --car', 'File is a CAR file.', false) + .option( + '--wrap', + 'Wrap single input file in a directory. Has no effect on directory or CAR uploads. Pass --no-wrap to disable.', + true + ) + .option('--json', 'Format as newline delimited JSON', false) + .option('--verbose', 'Output more details.', false) + .option( + '--shard-size', + 'Shard uploads into CAR files of approximately this size in bytes.' + ) + .option( + '--concurrent-requests', + 'Send up to this many CAR shards concurrently.' + ) + .action(upload) + +cli + .command('open ') + .describe('Open CID on https://w3s.link') + .action((cid) => open(`https://w3s.link/ipfs/${cid}`)) + +cli + .command('ls') + .alias('list') + .describe('List uploads in the current space') + .option('--json', 'Format as newline delimited JSON') + .option('--shards', 'Pretty print with shards in output') + .action(list) + +cli + .command('rm ') + .example('rm bafy...') + .describe( + 'Remove an upload from the uploads listing. Pass --shards to delete the actual data if you are sure no other uploads need them' + ) + .option( + '--shards', + 'Remove all shards referenced by the upload from the store. Use with caution and ensure other uploads do not reference the same shards.' + ) + .action(remove) + +cli + .command('whoami') + .describe('Print information about the current agent.') + .action(whoami) + +cli + .command('space create [name]') + .describe('Create a new storacha space') + .option('-nr, --no-recovery', 'Skips recovery key setup') + .option('-n, --no-caution', 'Prints out recovery key without confirmation') + .option('-nc, --no-customer', 'Skip billing setup') + .option('-c, --customer ', 'Billing account email') + .option('-na, --no-account', 'Skip account setup') + .option('-a, --account ', 'Managing account email') + .option( + '-ag, --authorize-gateway-services ', + 'Authorize Gateways to serve the content uploaded to this space, e.g: \'[{"id":"did:key:z6Mki...","serviceEndpoint":"https://gateway.example.com"}]\'' + ) + .option('-nga, --no-gateway-authorization', 'Skip Gateway Authorization') + .action((name, options) => { + let authorizeGatewayServices = [] + if (options['authorize-gateway-services']) { + try { + authorizeGatewayServices = JSON.parse( + options['authorize-gateway-services'] + ) + } catch (err) { + console.error('Invalid JSON format for --authorize-gateway-services') + process.exit(1) + } + } + + const parsedOptions = { + ...options, + // if defined it means we want to skip gateway authorization, so the client will not validate the gateway services + skipGatewayAuthorization: + options['gateway-authorization'] === false || + options['gateway-authorization'] === undefined, + // default to empty array if not set, so the client will validate the gateway services + authorizeGatewayServices: authorizeGatewayServices || [], + } + + return Space.create(name, parsedOptions) + }) + +cli + .command('space provision [name]') + .describe('Associating space with a billing account') + .option('-c, --customer', 'The email address of the billing account') + .option('--coupon', 'Coupon URL to provision space with') + .option('-p, -password', 'Coupon password') + .option( + '-p, --provider', + 'The storage provider to associate with this space.' + ) + .action(Space.provision) + +cli + .command('space add ') + .describe( + 'Import a space from a proof: a CAR encoded UCAN delegating capabilities to this agent. proof is a filesystem path, or a base64 encoded cid string.' + ) + .action(addSpace) + +cli + .command('space ls') + .describe('List spaces known to the agent') + .action(listSpaces) + +cli + .command('space info') + .describe('Show information about a space. Defaults to the current space.') + .option('-s, --space', 'The space to print information about.') + .option('--json', 'Format as newline delimited JSON') + .action(spaceInfo) + +cli + .command('space use ') + .describe('Set the current space in use by the agent') + .action(useSpace) + +cli + .command('coupon create ') + .option('--password', 'Password for created coupon.') + .option('-c, --can', 'One or more abilities to delegate.') + .option( + '-e, --expiration', + 'Unix timestamp when the delegation is no longer valid. Zero indicates no expiration.', + 0 + ) + .option( + '-o, --output', + 'Path of file to write the exported delegation data to.' + ) + .action(Coupon.issue) + +cli + .command('bridge generate-tokens ') + .option('-c, --can', 'One or more abilities to delegate.') + .option( + '-e, --expiration', + 'Unix timestamp (in seconds) when the delegation is no longer valid. Zero indicates no expiration.', + 0 + ) + .option( + '-j, --json', + 'If set, output JSON suitable to spread into the `headers` field of a `fetch` request.' + ) + .action(Bridge.generateTokens) + +cli + .command('delegation create ') + .describe( + 'Output a CAR encoded UCAN that delegates capabilities to the audience for the current space.' + ) + .option('-c, --can', 'One or more abilities to delegate.') + .option( + '-n, --name', + 'Human readable name for the audience receiving the delegation.' + ) + .option( + '-t, --type', + 'Type of the audience receiving the delegation, one of: device, app, service.' + ) + .option( + '-e, --expiration', + 'Unix timestamp when the delegation is no longer valid. Zero indicates no expiration.', + 0 + ) + .option( + '-o, --output', + 'Path of file to write the exported delegation data to.' + ) + .option( + '--base64', + 'Format as base64 identity CID string. Useful when saving it as an environment variable.' + ) + .action(createDelegation) + +cli + .command('delegation ls') + .describe('List delegations created by this agent for others.') + .option('--json', 'Format as newline delimited JSON') + .action(listDelegations) + +cli + .command('delegation revoke ') + .describe('Revoke a delegation by CID.') + .option( + '-p, --proof', + 'Name of a file containing the delegation and any additional proofs needed to prove authority to revoke' + ) + .action(revokeDelegation) + +cli + .command('proof add ') + .describe('Add a proof delegated to this agent.') + .option('--json', 'Format as newline delimited JSON') + .option('--dry-run', 'Decode and view the proof but do not add it') + .action(addProof) + +cli + .command('proof ls') + .describe('List proofs of capabilities delegated to this agent.') + .option('--json', 'Format as newline delimited JSON') + .action(listProofs) + +cli + .command('usage report') + .describe('Display report of current space usage in bytes.') + .option('--human', 'Format human readable values.', false) + .option('--json', 'Format as newline delimited JSON', false) + .action(usageReport) + +cli + .command('can access claim') + .describe('Claim delegated capabilities for the authorized account.') + .action(accessClaim) + +cli + .command('can blob add [data-path]') + .describe('Store a blob with the service.') + .action(blobAdd) + +cli + .command('can blob ls') + .describe('List blobs in the current space.') + .option('--json', 'Format as newline delimited JSON') + .option('--size', 'The desired number of results to return') + .option( + '--cursor', + 'An opaque string included in a prior blob/list response that allows the service to provide the next "page" of results' + ) + .action(blobList) + +cli + .command('can blob rm ') + .describe('Remove a blob from the store by base58btc encoded multihash.') + .action(blobRemove) + +cli + .command('can index add ') + .describe('Register an "index" with the service.') + .action(indexAdd) + +cli + .command('can upload add ') + .describe( + 'Register an upload - a DAG with the given root data CID that is stored in the given CAR shard(s), identified by CAR CIDs.' + ) + .action(uploadAdd) + +cli + .command('can upload ls') + .describe('List uploads in the current space.') + .option('--json', 'Format as newline delimited JSON') + .option('--shards', 'Pretty print with shards in output') + .option('--size', 'The desired number of results to return') + .option( + '--cursor', + 'An opaque string included in a prior upload/list response that allows the service to provide the next "page" of results' + ) + .option('--pre', 'If true, return the page of results preceding the cursor') + .action(uploadList) + +cli + .command('can upload rm ') + .describe('Remove an upload from the uploads listing.') + .action(uploadRemove) + +cli + .command('can filecoin info ') + .describe('Get filecoin information for given PieceCid.') + .action(filecoinInfo) + +cli + .command('key create') + .describe( + 'Generate and print a new ed25519 key pair. Does not change your current signing key.' + ) + .option('--json', 'output as json') + .action(createKey) + +cli + .command('reset') + .describe( + 'Remove all proofs/delegations from the store but retain the agent DID.' + ) + .action(reset) + +// show help text if no command provided +cli.command('help [cmd]', 'Show help text', { default: true }).action((cmd) => { + try { + cli.help(cmd) + } catch (err) { + console.log(` +ERROR + Invalid command: ${cmd} + +Run \`$ storacha --help\` for more info. +`) + process.exit(1) + } +}) + +cli.parse(process.argv) diff --git a/packages/cli/bridge.js b/packages/cli/bridge.js new file mode 100644 index 000000000..f3df16c32 --- /dev/null +++ b/packages/cli/bridge.js @@ -0,0 +1,68 @@ +import * as DID from '@ipld/dag-ucan/did' +import * as Account from './account.js' +import * as Space from './space.js' +import { getClient } from './lib.js' +import * as ucanto from '@ucanto/core' +import { base64url } from 'multiformats/bases/base64' +import cryptoRandomString from 'crypto-random-string' + +export { Account, Space } + +/** + * @typedef {object} BridgeGenerateTokensOptions + * @property {string} resource + * @property {string[]|string} [can] + * @property {number} [expiration] + * @property {boolean} [json] + * + * @param {string} resource + * @param {BridgeGenerateTokensOptions} options + */ +export const generateTokens = async ( + resource, + { can = ['store/add', 'upload/add'], expiration, json } +) => { + const client = await getClient() + + const resourceDID = DID.parse(resource) + const abilities = can ? [can].flat() : [] + if (!abilities.length) { + console.error('Error: missing capabilities for delegation') + process.exit(1) + } + + const capabilities = /** @type {ucanto.API.Capabilities} */ ( + abilities.map((can) => ({ can, with: resourceDID.did() })) + ) + + const password = cryptoRandomString({ length: 32 }) + + const coupon = await client.coupon.issue({ + capabilities, + expiration: expiration === 0 ? Infinity : expiration, + password, + }) + + const { ok: bytes, error } = await coupon.archive() + if (!bytes) { + console.error(error) + return process.exit(1) + } + const xAuthSecret = base64url.encode(new TextEncoder().encode(password)) + const authorization = base64url.encode(bytes) + + if (json) { + console.log( + JSON.stringify({ + 'X-Auth-Secret': xAuthSecret, + Authorization: authorization, + }) + ) + } else { + console.log(` +X-Auth-Secret header: ${xAuthSecret} + +Authorization header: ${authorization} + `) + } +} diff --git a/packages/cli/can.js b/packages/cli/can.js new file mode 100644 index 000000000..569848642 --- /dev/null +++ b/packages/cli/can.js @@ -0,0 +1,224 @@ +/* eslint-env browser */ +import fs from 'node:fs' +import { Readable } from 'node:stream' +import * as Link from 'multiformats/link' +import * as raw from 'multiformats/codecs/raw' +import { base58btc } from 'multiformats/bases/base58' +import * as Digest from 'multiformats/hashes/digest' +import { Piece } from '@web3-storage/data-segment' +import ora from 'ora' +import { + getClient, + uploadListResponseToString, + filecoinInfoToString, + parseCarLink, + streamToBlob, + blobListResponseToString, +} from './lib.js' + +/** + * @param {string} [blobPath] + */ +export async function blobAdd(blobPath) { + const client = await getClient() + + const spinner = ora('Reading data').start() + /** @type {Blob} */ + let blob + try { + blob = await streamToBlob( + /** @type {ReadableStream} */ + (Readable.toWeb(blobPath ? fs.createReadStream(blobPath) : process.stdin)) + ) + } catch (/** @type {any} */ err) { + spinner.fail(`Error: failed to read data: ${err.message}`) + process.exit(1) + } + + spinner.start('Storing') + const { digest } = await client.capability.blob.add(blob, { + receiptsEndpoint: client._receiptsEndpoint.toString(), + }) + const cid = Link.create(raw.code, digest) + spinner.stopAndPersist({ + symbol: '⁂', + text: `Stored ${base58btc.encode(digest.bytes)} (${cid})`, + }) +} + +/** + * Print out all the blobs in the current space. + * + * @param {object} opts + * @param {boolean} [opts.json] + * @param {string} [opts.cursor] + * @param {number} [opts.size] + */ +export async function blobList(opts = {}) { + const client = await getClient() + const listOptions = {} + if (opts.size) { + listOptions.size = parseInt(String(opts.size)) + } + if (opts.cursor) { + listOptions.cursor = opts.cursor + } + + const spinner = ora('Listing Blobs').start() + const res = await client.capability.blob.list(listOptions) + spinner.stop() + console.log(blobListResponseToString(res, opts)) +} + +/** + * @param {string} digestStr + */ +export async function blobRemove(digestStr) { + const spinner = ora(`Removing ${digestStr}`).start() + let digest + try { + digest = Digest.decode(base58btc.decode(digestStr)) + } catch { + spinner.fail(`Error: "${digestStr}" is not a base58btc encoded multihash`) + process.exit(1) + } + const client = await getClient() + try { + await client.capability.blob.remove(digest) + spinner.stopAndPersist({ symbol: '⁂', text: `Removed ${digestStr}` }) + } catch (/** @type {any} */ err) { + spinner.fail(`Error: blob remove failed: ${err.message ?? err}`) + console.error(err) + process.exit(1) + } +} + +/** + * @param {string} cidStr + */ +export async function indexAdd(cidStr) { + const client = await getClient() + + const spinner = ora('Adding').start() + const cid = parseCarLink(cidStr) + if (!cid) { + spinner.fail(`Error: "${cidStr}" is not a valid index CID`) + process.exit(1) + } + await client.capability.index.add(cid) + spinner.stopAndPersist({ symbol: '⁂', text: `Added index ${cid}` }) +} + +/** + * @param {string} root + * @param {string} shard + * @param {object} opts + * @param {string[]} opts._ + */ +export async function uploadAdd(root, shard, opts) { + const client = await getClient() + + let rootCID + try { + rootCID = Link.parse(root) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to parse root CID: ${root}: ${err.message}`) + process.exit(1) + } + + /** @type {import('@storacha/client/types').CARLink[]} */ + const shards = [] + for (const str of [shard, ...opts._]) { + try { + shards.push(Link.parse(str)) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to parse shard CID: ${str}: ${err.message}`) + process.exit(1) + } + } + + const spinner = ora('Adding upload').start() + await client.capability.upload.add(rootCID, shards) + spinner.stopAndPersist({ symbol: '⁂', text: `Upload added ${rootCID}` }) +} + +/** + * Print out all the uploads in the current space. + * + * @param {object} opts + * @param {boolean} [opts.json] + * @param {boolean} [opts.shards] + * @param {string} [opts.cursor] + * @param {number} [opts.size] + * @param {boolean} [opts.pre] + */ +export async function uploadList(opts = {}) { + const client = await getClient() + const listOptions = {} + if (opts.size) { + listOptions.size = parseInt(String(opts.size)) + } + if (opts.cursor) { + listOptions.cursor = opts.cursor + } + if (opts.pre) { + listOptions.pre = opts.pre + } + + const spinner = ora('Listing uploads').start() + const res = await client.capability.upload.list(listOptions) + spinner.stop() + console.log(uploadListResponseToString(res, opts)) +} + +/** + * Remove the upload from the upload list. + * + * @param {string} rootCid + */ +export async function uploadRemove(rootCid) { + let root + try { + root = Link.parse(rootCid.trim()) + } catch (/** @type {any} */ err) { + console.error(`Error: ${rootCid} is not a CID`) + process.exit(1) + } + const client = await getClient() + try { + await client.capability.upload.remove(root) + } catch (/** @type {any} */ err) { + console.error(`Upload remove failed: ${err.message ?? err}`) + console.error(err) + process.exit(1) + } +} + +/** + * Get filecoin information for given PieceCid. + * + * @param {string} pieceCid + * @param {object} opts + * @param {boolean} [opts.json] + * @param {boolean} [opts.raw] + */ +export async function filecoinInfo(pieceCid, opts) { + let pieceInfo + try { + pieceInfo = Piece.fromString(pieceCid) + } catch (/** @type {any} */ err) { + console.error(`Error: ${pieceCid} is not a Link`) + process.exit(1) + } + const spinner = ora('Getting filecoin info').start() + const client = await getClient() + const info = await client.capability.filecoin.info(pieceInfo.link) + if (info.out.error) { + spinner.fail( + `Error: failed to get filecoin info: ${info.out.error.message}` + ) + process.exit(1) + } + spinner.stop() + console.log(filecoinInfoToString(info.out.ok, opts)) +} diff --git a/packages/cli/coupon.js b/packages/cli/coupon.js new file mode 100644 index 000000000..0be7032e6 --- /dev/null +++ b/packages/cli/coupon.js @@ -0,0 +1,55 @@ +import fs from 'node:fs/promises' +import * as DID from '@ipld/dag-ucan/did' +import * as Account from './account.js' +import * as Space from './space.js' +import { getClient } from './lib.js' +import * as ucanto from '@ucanto/core' + +export { Account, Space } + +/** + * @typedef {object} CouponIssueOptions + * @property {string} customer + * @property {string[]|string} [can] + * @property {string} [password] + * @property {number} [expiration] + * @property {string} [output] + * + * @param {string} customer + * @param {CouponIssueOptions} options + */ +export const issue = async ( + customer, + { can = 'provider/add', expiration, password, output } +) => { + const client = await getClient() + + const audience = DID.parse(customer) + const abilities = can ? [can].flat() : [] + if (!abilities.length) { + console.error('Error: missing capabilities for delegation') + process.exit(1) + } + + const capabilities = /** @type {ucanto.API.Capabilities} */ ( + abilities.map((can) => ({ can, with: audience.did() })) + ) + + const coupon = await client.coupon.issue({ + capabilities, + expiration: expiration === 0 ? Infinity : expiration, + password, + }) + + const { ok: bytes, error } = await coupon.archive() + if (!bytes) { + console.error(error) + return process.exit(1) + } + + if (output) { + await fs.writeFile(output, bytes) + } else { + process.stdout.write(bytes) + } +} diff --git a/packages/cli/dialog.js b/packages/cli/dialog.js new file mode 100644 index 000000000..b4502e20b --- /dev/null +++ b/packages/cli/dialog.js @@ -0,0 +1,148 @@ +import { useState, useKeypress, createPrompt, isEnterKey } from '@inquirer/core' +import chalk from 'chalk' +import ansiEscapes from 'ansi-escapes' +/** + * @typedef {'concealed'|'revealed'|'validating'|'done'} Status + * @typedef {object} MnemonicOptions + * @property {string[]} secret + * @property {string} message + * @property {string} [prefix] + * @property {string} [revealMessage] + * @property {string} [submitMessage] + * @property {string} [validateMessage] + * @property {string} [exitMessage] + */ +export const mnemonic = createPrompt( + /** + * @param {MnemonicOptions} config + * @param {(answer: unknown) => void} done + */ + ( + { + prefix = '🔑', + message, + secret, + revealMessage = 'When ready, hit enter to reveal the key', + submitMessage = 'Please save the key and then hit enter to continue', + validateMessage = 'Please type or paste key to ensure it is correct', + exitMessage = 'Key matched!', + }, + done + ) => { + const [status, setStatus] = useState(/** @type {Status} */ ('concealed')) + const [input, setInput] = useState('') + + useKeypress((key, io) => { + switch (status) { + case 'concealed': + if (isEnterKey(key)) { + setStatus('revealed') + } + return + case 'revealed': + if (isEnterKey(key)) { + setStatus('validating') + } + return + case 'validating': { + // if line break is pasted or typed we want interpret it as + // a space character, this is why we write current input back + // to the terminal with a trailing space. That way user will + // still be able to edit the input afterwards. + if (isEnterKey(key)) { + io.write(`${input} `) + } else { + // If current input matches the secret we are done. + const input = parseInput(io.line) + setInput(io.line) + if (input.join('') === secret.join('')) { + setStatus('done') + done({}) + } + } + return + } + default: + return done({}) + } + }) + + switch (status) { + case 'concealed': + return show({ + prefix, + message, + key: conceal(secret), + hint: revealMessage, + }) + case 'revealed': + return show({ prefix, message, key: secret, hint: submitMessage }) + case 'validating': + return show({ + prefix, + message, + key: diff(parseInput(input), secret), + hint: validateMessage, + }) + case 'done': + return show({ + prefix, + message, + key: conceal(secret, CORRECT), + hint: exitMessage, + }) + } + } +) + +/** + * @param {string} input + */ +const parseInput = (input) => input.trim().split(/[\n\s]+/) + +/** + * @param {string[]} input + * @param {string[]} key + */ +const diff = (input, key) => { + const source = input.join('') + let offset = 0 + const output = [] + for (const word of key) { + let delta = [] + for (const expect of word) { + const actual = source[offset] + if (actual === expect) { + delta.push(CORRECT) + } else if (actual != undefined) { + delta.push(chalk.inverse.strikethrough.red(actual)) + } else { + delta.push(CONCEAL) + } + offset++ + } + output.push(delta.join('')) + } + + return output +} + +/** + * @param {object} state + * @param {string} state.prefix + * @param {string} state.message + * @param {string[]} state.key + * @param {string} state.hint + */ +const show = ({ prefix, message, key, hint }) => + `${prefix} ${message}\n\n${key.join(' ')}\n\n${hint}${ansiEscapes.cursorHide}` + +/** + * @param {string[]} key + * @param {string} [char] + */ +const conceal = (key, char = CONCEAL) => + key.map((word) => char.repeat(word.length)) + +const CONCEAL = '█' +const CORRECT = chalk.inverse('•') diff --git a/packages/cli/index.js b/packages/cli/index.js new file mode 100644 index 000000000..11731c2db --- /dev/null +++ b/packages/cli/index.js @@ -0,0 +1,721 @@ +import fs from 'node:fs' +import { pipeline } from 'node:stream/promises' +import { Readable } from 'node:stream' +import ora from 'ora' +import { CID } from 'multiformats/cid' +import { base64 } from 'multiformats/bases/base64' +import { identity } from 'multiformats/hashes/identity' +import * as Digest from 'multiformats/hashes/digest' +import * as DID from '@ipld/dag-ucan/did' +import * as dagJSON from '@ipld/dag-json' +import { CarWriter } from '@ipld/car' +import { filesFromPaths } from 'files-from-path' +import * as PieceHasher from 'fr32-sha2-256-trunc254-padded-binary-tree-multihash' +import * as Account from './account.js' + +import { spaceAccess } from '@storacha/client/capability/access' +import { AgentData } from '@storacha/access' +import * as Space from './space.js' +import { + getClient, + getStore, + checkPathsExist, + filesize, + filesizeMB, + readProof, + readProofFromBytes, + uploadListResponseToString, + startOfLastMonth, +} from './lib.js' +import * as ucanto from '@ucanto/core' +import { ed25519 } from '@ucanto/principal' +import chalk from 'chalk' +export * as Coupon from './coupon.js' +export * as Bridge from './bridge.js' +export { Account, Space } +import ago from 's-ago' + +/** + * + */ +export async function accessClaim() { + const client = await getClient() + await client.capability.access.claim() +} + +/** + * @param {string} email + */ +export const getPlan = async (email = '') => { + const client = await getClient() + const account = + email === '' + ? await Space.selectAccount(client) + : await Space.useAccount(client, { email }) + + if (account) { + const { ok: plan, error } = await account.plan.get() + if (plan) { + console.log(`⁂ ${plan.product}`) + } else if (error?.name === 'PlanNotFound') { + console.log('⁂ no plan has been selected yet') + } else { + console.error(`Failed to get plan - ${error.message}`) + process.exit(1) + } + } else { + process.exit(1) + } +} + +/** + * @param {`${string}@${string}`} email + * @param {object} [opts] + * @param {import('@ucanto/interface').Ability[]|import('@ucanto/interface').Ability} [opts.can] + */ +export async function authorize(email, opts = {}) { + const client = await getClient() + const capabilities = + opts.can != null ? [opts.can].flat().map((can) => ({ can })) : undefined + /** @type {import('ora').Ora|undefined} */ + let spinner + setTimeout(() => { + spinner = ora( + `🔗 please click the link we sent to ${email} to authorize this agent` + ).start() + }, 1000) + try { + await client.authorize(email, { capabilities }) + } catch (err) { + if (spinner) spinner.stop() + console.error(err) + process.exit(1) + } + if (spinner) spinner.stop() + console.log(`⁂ agent authorized to use capabilities delegated to ${email}`) +} + +/** + * @param {string} firstPath + * @param {{ + * _: string[], + * car?: boolean + * hidden?: boolean + * json?: boolean + * verbose?: boolean + * wrap?: boolean + * 'shard-size'?: number + * 'concurrent-requests'?: number + * }} [opts] + */ +export async function upload(firstPath, opts) { + /** @type {import('@storacha/client/types').FileLike[]} */ + let files + /** @type {number} */ + let totalSize // -1 when unknown size (input from stdin) + /** @type {import('ora').Ora} */ + let spinner + const client = await getClient() + if (firstPath) { + const paths = checkPathsExist([firstPath, ...(opts?._ ?? [])]) + const hidden = !!opts?.hidden + spinner = ora({ text: 'Reading files', isSilent: opts?.json }).start() + const localFiles = await filesFromPaths(paths, { hidden }) + totalSize = localFiles.reduce((total, f) => total + f.size, 0) + files = localFiles + spinner.stopAndPersist({ + text: `${files.length} file${files.length === 1 ? '' : 's'} ${chalk.dim( + filesize(totalSize) + )}`, + }) + + if (opts?.car && files.length > 1) { + console.error('Error: multiple CAR files not supported') + process.exit(1) + } + } else { + spinner = ora({ text: 'Reading from stdin', isSilent: opts?.json }).start() + files = [ + { + name: 'stdin', + stream: () => + /** @type {ReadableStream} */ + (Readable.toWeb(process.stdin)), + }, + ] + totalSize = -1 + opts = opts ?? { _: [] } + opts.wrap = false + } + + spinner.start('Storing') + /** @type {(o?: import('@storacha/client/src/types').UploadOptions) => Promise} */ + const uploadFn = opts?.car + ? client.uploadCAR.bind(client, files[0]) + : files.length === 1 && opts?.wrap === false + ? client.uploadFile.bind(client, files[0]) + : client.uploadDirectory.bind(client, files) + + let totalSent = 0 + const getStoringMessage = () => + totalSize == -1 + ? // for unknown size, display the amount sent so far + `Storing ${filesizeMB(totalSent)}` + : // for known size, display percentage of total size that has been sent + `Storing ${Math.min(Math.round((totalSent / totalSize) * 100), 100)}%` + + const root = await uploadFn({ + pieceHasher: { + code: PieceHasher.code, + name: 'fr32-sha2-256-trunc254-padded-binary-tree-multihash', + async digest(input) { + const hasher = PieceHasher.create() + hasher.write(input) + + const bytes = new Uint8Array(hasher.multihashByteLength()) + hasher.digestInto(bytes, 0, true) + hasher.free() + + return Digest.decode(bytes) + }, + }, + onShardStored: ({ cid, size, piece }) => { + totalSent += size + if (opts?.verbose) { + spinner.stopAndPersist({ + text: `${cid} ${chalk.dim(filesizeMB(size))}\n${chalk.dim( + ' └── ' + )}Piece CID: ${piece}`, + }) + spinner.start(getStoringMessage()) + } else { + spinner.text = getStoringMessage() + } + opts?.json && + opts?.verbose && + console.log(dagJSON.stringify({ shard: cid, size, piece })) + }, + shardSize: opts?.['shard-size'] && parseInt(String(opts?.['shard-size'])), + concurrentRequests: + opts?.['concurrent-requests'] && + parseInt(String(opts?.['concurrent-requests'])), + receiptsEndpoint: client._receiptsEndpoint.toString(), + }) + spinner.stopAndPersist({ + symbol: '⁂', + text: `Stored ${files.length} file${files.length === 1 ? '' : 's'}`, + }) + console.log( + opts?.json ? dagJSON.stringify({ root }) : `⁂ https://w3s.link/ipfs/${root}` + ) +} + +/** + * Print out all the uploads in the current space. + * + * @param {object} opts + * @param {boolean} [opts.json] + * @param {boolean} [opts.shards] + */ +export async function list(opts = {}) { + const client = await getClient() + let count = 0 + /** @type {import('@storacha/client/types').UploadListSuccess|undefined} */ + let res + do { + res = await client.capability.upload.list({ cursor: res?.cursor }) + if (!res) throw new Error('missing upload list response') + count += res.results.length + if (res.results.length) { + console.log(uploadListResponseToString(res, opts)) + } + } while (res.cursor && res.results.length) + + if (count === 0 && !opts.json) { + console.log('⁂ No uploads in space') + console.log('⁂ Try out `storacha up ` to upload some') + } +} +/** + * @param {string} rootCid + * @param {object} opts + * @param {boolean} [opts.shards] + */ +export async function remove(rootCid, opts) { + let root + try { + root = CID.parse(rootCid.trim()) + } catch (/** @type {any} */ err) { + console.error(`Error: ${rootCid} is not a CID`) + process.exit(1) + } + const client = await getClient() + + try { + await client.remove(root, opts) + } catch (/** @type {any} */ err) { + console.error(`Remove failed: ${err.message ?? err}`) + console.error(err) + process.exit(1) + } +} + +/** + * @param {string} name + */ +export async function createSpace(name) { + const client = await getClient() + const space = await client.createSpace(name, { + skipGatewayAuthorization: true, + }) + await client.setCurrentSpace(space.did()) + console.log(space.did()) +} + +/** + * @param {string} proofPathOrCid + */ +export async function addSpace(proofPathOrCid) { + const client = await getClient() + + let cid + try { + cid = CID.parse(proofPathOrCid, base64) + } catch (/** @type {any} */ err) { + if (err?.message?.includes('Unexpected end of data')) { + console.error( + `Error: failed to read proof. The string has been truncated.` + ) + process.exit(1) + } + /* otherwise, try as path */ + } + + let delegation + if (cid) { + if (cid.multihash.code !== identity.code) { + console.error( + `Error: failed to read proof. Must be identity CID. Fetching of remote proof CARs not supported by this command yet` + ) + process.exit(1) + } + delegation = await readProofFromBytes(cid.multihash.digest) + } else { + delegation = await readProof(proofPathOrCid) + } + + const space = await client.addSpace(delegation) + console.log(space.did()) +} + +/** + * + */ +export async function listSpaces() { + const client = await getClient() + const current = client.currentSpace() + for (const space of client.spaces()) { + const prefix = current && current.did() === space.did() ? '* ' : ' ' + console.log(`${prefix}${space.did()} ${space.name ?? ''}`) + } +} + +/** + * @param {string} did + */ +export async function useSpace(did) { + const client = await getClient() + const spaces = client.spaces() + const space = + spaces.find((s) => s.did() === did) ?? spaces.find((s) => s.name === did) + if (!space) { + console.error(`Error: space not found: ${did}`) + process.exit(1) + } + await client.setCurrentSpace(space.did()) + console.log(space.did()) +} + +/** + * @param {object} opts + * @param {import('@storacha/client/types').DID} [opts.space] + * @param {string} [opts.json] + */ +export async function spaceInfo(opts) { + const client = await getClient() + const spaceDID = opts.space ?? client.currentSpace()?.did() + if (!spaceDID) { + throw new Error( + 'no current space and no space given: please use --space to specify a space or select one using "space use"' + ) + } + + /** @type {import('@storacha/access/types').SpaceInfoResult} */ + let info + try { + info = await client.capability.space.info(spaceDID) + } catch (/** @type {any} */ err) { + // if the space was not known to the service then that's ok, there's just + // no info to print about it. Don't make it look like something is wrong, + // just print the space DID since that's all we know. + if (err.name === 'SpaceUnknown') { + // @ts-expect-error spaceDID should be a did:key + info = { did: spaceDID } + } else { + return console.log(`Error getting info about ${spaceDID}: ${err.message}`) + } + } + + const space = client.spaces().find((s) => s.did() === spaceDID) + const name = space ? space.name : undefined + + if (opts.json) { + console.log(JSON.stringify({ ...info, name }, null, 4)) + } else { + const providers = info.providers?.join(', ') ?? '' + console.log(` + DID: ${info.did} +Providers: ${providers || chalk.dim('none')} + Name: ${name ?? chalk.dim('none')}`) + } +} + +/** + * @param {string} audienceDID + * @param {object} opts + * @param {string[]|string} opts.can + * @param {string} [opts.name] + * @param {string} [opts.type] + * @param {number} [opts.expiration] + * @param {string} [opts.output] + * @param {string} [opts.with] + * @param {boolean} [opts.base64] + */ +export async function createDelegation(audienceDID, opts) { + const client = await getClient() + + if (client.currentSpace() == null) { + throw new Error( + 'no current space, use `storacha space register` to create one.' + ) + } + const audience = DID.parse(audienceDID) + + const abilities = opts.can ? [opts.can].flat() : Object.keys(spaceAccess) + if (!abilities.length) { + console.error('Error: missing capabilities for delegation') + process.exit(1) + } + const audienceMeta = {} + if (opts.name) audienceMeta.name = opts.name + if (opts.type) audienceMeta.type = opts.type + const expiration = opts.expiration || Infinity + + // @ts-expect-error createDelegation should validate abilities + const delegation = await client.createDelegation(audience, abilities, { + expiration, + audienceMeta, + }) + + const { writer, out } = CarWriter.create() + const dest = opts.output ? fs.createWriteStream(opts.output) : process.stdout + + void pipeline( + out, + async function* maybeBaseEncode(src) { + const chunks = [] + for await (const chunk of src) { + if (!opts.base64) { + yield chunk + } else { + chunks.push(chunk) + } + } + if (!opts.base64) return + const blob = new Blob(chunks) + const bytes = new Uint8Array(await blob.arrayBuffer()) + const idCid = CID.createV1(ucanto.CAR.code, identity.digest(bytes)) + yield idCid.toString(base64) + }, + dest + ) + + for (const block of delegation.export()) { + // @ts-expect-error + await writer.put(block) + } + await writer.close() +} + +/** + * @param {object} opts + * @param {boolean} [opts.json] + */ +export async function listDelegations(opts) { + const client = await getClient() + const delegations = client.delegations() + if (opts.json) { + for (const delegation of delegations) { + console.log( + JSON.stringify({ + cid: delegation.cid.toString(), + audience: delegation.audience.did(), + capabilities: delegation.capabilities.map((c) => ({ + with: c.with, + can: c.can, + })), + }) + ) + } + } else { + for (const delegation of delegations) { + console.log(delegation.cid.toString()) + console.log(` audience: ${delegation.audience.did()}`) + for (const capability of delegation.capabilities) { + console.log(` with: ${capability.with}`) + console.log(` can: ${capability.can}`) + } + } + } +} + +/** + * @param {string} delegationCid + * @param {object} opts + * @param {string} [opts.proof] + */ +export async function revokeDelegation(delegationCid, opts) { + const client = await getClient() + let proof + try { + if (opts.proof) { + proof = await readProof(opts.proof) + } + } catch (/** @type {any} */ err) { + console.log(`Error: reading proof: ${err.message}`) + process.exit(1) + } + let cid + try { + // TODO: we should validate that this is a UCANLink + cid = ucanto.parseLink(delegationCid.trim()) + } catch (/** @type {any} */ err) { + console.error(`Error: invalid CID: ${delegationCid}: ${err.message}`) + process.exit(1) + } + const result = await client.revokeDelegation( + /** @type {import('@ucanto/interface').UCANLink} */ (cid), + { proofs: proof ? [proof] : [] } + ) + if (result.ok) { + console.log(`⁂ delegation ${delegationCid} revoked`) + } else { + console.error(`Error: revoking ${delegationCid}: ${result.error?.message}`) + process.exit(1) + } +} + +/** + * @param {string} proofPath + * @param {{ json?: boolean, 'dry-run'?: boolean }} [opts] + */ +export async function addProof(proofPath, opts) { + const client = await getClient() + let proof + try { + proof = await readProof(proofPath) + if (!opts?.['dry-run']) { + await client.addProof(proof) + } + } catch (/** @type {any} */ err) { + console.log(`Error: ${err.message}`) + process.exit(1) + } + if (opts?.json) { + console.log(JSON.stringify(proof.toJSON())) + } else { + console.log(proof.cid.toString()) + console.log(` issuer: ${proof.issuer.did()}`) + for (const capability of proof.capabilities) { + console.log(` with: ${capability.with}`) + console.log(` can: ${capability.can}`) + } + } +} + +/** + * @param {object} opts + * @param {boolean} [opts.json] + */ +export async function listProofs(opts) { + const client = await getClient() + const proofs = client.proofs() + if (opts.json) { + for (const proof of proofs) { + console.log(JSON.stringify(proof)) + } + } else { + for (const proof of proofs) { + console.log(chalk.dim(`# ${proof.cid.toString()}`)) + console.log(`iss: ${chalk.cyanBright(proof.issuer.did())}`) + if (proof.expiration !== Infinity) { + console.log( + `exp: ${chalk.yellow(proof.expiration)} ${chalk.dim( + ` # expires ${ago(new Date(proof.expiration * 1000))}` + )}` + ) + } + console.log('att:') + for (const capability of proof.capabilities) { + console.log(` - can: ${chalk.magentaBright(capability.can)}`) + console.log(` with: ${chalk.green(capability.with)}`) + if (capability.nb) { + console.log(` nb: ${JSON.stringify(capability.nb)}`) + } + } + if (proof.facts.length > 0) { + console.log('fct:') + } + for (const fact of proof.facts) { + console.log(` - ${JSON.stringify(fact)}`) + } + console.log('') + } + console.log( + chalk.dim( + `# ${proofs.length} proof${ + proofs.length === 1 ? '' : 's' + } for ${client.agent.did()}` + ) + ) + } +} + +/** + * + */ +export async function whoami() { + const client = await getClient() + console.log(client.did()) +} + +/** + * @param {object} [opts] + * @param {boolean} [opts.human] + * @param {boolean} [opts.json] + */ +export async function usageReport(opts) { + const client = await getClient() + const now = new Date() + const period = { + // we may not have done a snapshot for this month _yet_, so get report from last month -> now + from: startOfLastMonth(now), + to: now, + } + const failures = [] + let total = 0 + for await (const result of getSpaceUsageReports(client, period)) { + if ('error' in result) { + failures.push(result) + } else { + if (opts?.json) { + const { account, provider, space, size } = result + console.log( + dagJSON.stringify({ + account, + provider, + space, + size, + reportedAt: now.toISOString(), + }) + ) + } else { + const { account, provider, space, size } = result + console.log(` Account: ${account}`) + console.log(`Provider: ${provider}`) + console.log(` Space: ${space}`) + console.log( + ` Size: ${opts?.human ? filesize(size.final) : size.final}\n` + ) + } + total += result.size.final + } + } + if (!opts?.json) { + console.log(` Total: ${opts?.human ? filesize(total) : total}`) + if (failures.length) { + console.warn(``) + console.warn( + ` WARNING: there were ${failures.length} errors getting usage reports for some spaces.` + ) + console.warn( + ` This may happen if your agent does not have usage/report authorization for a space.` + ) + console.warn( + ` These spaces were not included in the usage report total:` + ) + for (const fail of failures) { + console.warn(` * space: ${fail.space}`) + // @ts-expect-error error is unknown + console.warn(` error: ${fail.error?.message}`) + console.warn(` account: ${fail.account}`) + } + } + } +} + +/** + * @param {import('@storacha/client').Client} client + * @param {{ from: Date, to: Date }} period + */ +async function* getSpaceUsageReports(client, period) { + for (const account of Object.values(client.accounts())) { + const subscriptions = await client.capability.subscription.list( + account.did() + ) + for (const { consumers } of subscriptions.results) { + for (const space of consumers) { + /** @type {import('@storacha/client/types').UsageReportSuccess} */ + let result + try { + result = await client.capability.usage.report(space, period) + } catch (error) { + yield { error, space, period, consumers, account: account.did() } + continue + } + for (const [, report] of Object.entries(result)) { + yield { account: account.did(), ...report } + } + } + } + } +} + +/** + * @param {{ json: boolean }} options + */ +export async function createKey({ json }) { + const signer = await ed25519.generate() + const key = ed25519.format(signer) + if (json) { + console.log(JSON.stringify({ did: signer.did(), key }, null, 2)) + } else { + console.log(`# ${signer.did()}`) + console.log(key) + } +} + +export const reset = async () => { + const store = getStore() + const exportData = await store.load() + if (exportData) { + let data = AgentData.fromExport(exportData) + // do not reset the principal + data = await AgentData.create({ + principal: data.principal, + meta: data.meta, + }) + await store.save(data.export()) + } + console.log('⁂ Agent reset.') +} diff --git a/packages/cli/lib.js b/packages/cli/lib.js new file mode 100644 index 000000000..8215b3363 --- /dev/null +++ b/packages/cli/lib.js @@ -0,0 +1,310 @@ +import fs from 'node:fs' +import path from 'node:path' +// @ts-expect-error no typings :( +import tree from 'pretty-tree' +import { importDAG } from '@ucanto/core/delegation' +import { connect } from '@ucanto/client' +import * as CAR from '@ucanto/transport/car' +import * as HTTP from '@ucanto/transport/http' +import * as Signer from '@ucanto/principal/ed25519' +import * as Link from 'multiformats/link' +import { base58btc } from 'multiformats/bases/base58' +import * as Digest from 'multiformats/hashes/digest' +import * as raw from 'multiformats/codecs/raw' +import { parse } from '@ipld/dag-ucan/did' +import * as dagJSON from '@ipld/dag-json' +import { create } from '@storacha/client' +import { StoreConf } from '@storacha/client/stores/conf' +import { CarReader } from '@ipld/car' + +/** + * @typedef {import('@storacha/client/types').AnyLink} AnyLink + * @typedef {import('@storacha/client/types').CARLink} CARLink + * @typedef {import('@storacha/client/types').FileLike & { size: number }} FileLike + * @typedef {import('@storacha/client/types').SpaceBlobListSuccess} BlobListSuccess + * @typedef {import('@storacha/client/types').UploadListSuccess} UploadListSuccess + * @typedef {import('@storacha/capabilities/types').FilecoinInfoSuccess} FilecoinInfoSuccess + */ + +/** + * + */ +export function getPkg() { + // @ts-ignore JSON.parse works with Buffer in Node.js + return JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url))) +} + +/** @param {string[]|string} paths */ +export function checkPathsExist(paths) { + paths = Array.isArray(paths) ? paths : [paths] + for (const p of paths) { + if (!fs.existsSync(p)) { + console.error(`The path ${path.resolve(p)} does not exist`) + process.exit(1) + } + } + return paths +} + +/** @param {number} bytes */ +export function filesize(bytes) { + if (bytes < 50) return `${bytes}B` // avoid 0.0KB + if (bytes < 50000) return `${(bytes / 1000).toFixed(1)}KB` // avoid 0.0MB + if (bytes < 50000000) return `${(bytes / 1000 / 1000).toFixed(1)}MB` // avoid 0.0GB + return `${(bytes / 1000 / 1000 / 1000).toFixed(1)}GB` +} + +/** @param {number} bytes */ +export function filesizeMB(bytes) { + return `${(bytes / 1000 / 1000).toFixed(1)}MB` +} + +/** Get a configured w3up store used by the CLI. */ +export function getStore() { + return new StoreConf({ + profile: process.env.STORACHA_STORE_NAME ?? 'storacha-cli', + }) +} + +/** + * Get a new API client configured from env vars. + */ +export function getClient() { + const store = getStore() + + const uploadServiceDID = process.env.STORACHA_SERVICE_DID + ? parse(process.env.STORACHA_SERVICE_DID) + : undefined + const uploadServiceURL = process.env.STORACHA_SERVICE_URL + ? new URL(process.env.STORACHA_SERVICE_URL) + : undefined + const receiptsEndpointString = process.env.STORACHA_RECEIPTS_URL + let receiptsEndpoint + if (receiptsEndpointString) { + receiptsEndpoint = new URL(receiptsEndpointString) + } + + let serviceConf + if (uploadServiceDID && uploadServiceURL) { + serviceConf = + /** @type {import('@storacha/client/types').ServiceConf} */ + ({ + access: connect({ + id: uploadServiceDID, + codec: CAR.outbound, + channel: HTTP.open({ url: uploadServiceURL, method: 'POST' }), + }), + upload: connect({ + id: uploadServiceDID, + codec: CAR.outbound, + channel: HTTP.open({ url: uploadServiceURL, method: 'POST' }), + }), + filecoin: connect({ + id: uploadServiceDID, + codec: CAR.outbound, + channel: HTTP.open({ url: uploadServiceURL, method: 'POST' }), + }), + }) + } + + /** @type {import('@storacha/client/types').ClientFactoryOptions} */ + const createConfig = { store, serviceConf, receiptsEndpoint } + + const principal = process.env.STORACHA_PRINCIPAL + if (principal) { + createConfig.principal = Signer.parse(principal) + } + + return create(createConfig) +} + +/** + * @param {string} path Path to the proof file. + */ +export async function readProof(path) { + let bytes + try { + const buff = await fs.promises.readFile(path) + bytes = new Uint8Array(buff.buffer) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to read proof: ${err.message}`) + process.exit(1) + } + return readProofFromBytes(bytes) +} + +/** + * @param {Uint8Array} bytes Path to the proof file. + */ +export async function readProofFromBytes(bytes) { + const blocks = [] + try { + const reader = await CarReader.fromBytes(bytes) + for await (const block of reader.blocks()) { + blocks.push(block) + } + } catch (/** @type {any} */ err) { + console.error(`Error: failed to parse proof: ${err.message}`) + process.exit(1) + } + try { + // @ts-expect-error + return importDAG(blocks) + } catch (/** @type {any} */ err) { + console.error(`Error: failed to import proof: ${err.message}`) + process.exit(1) + } +} + +/** + * @param {UploadListSuccess} res + * @param {object} [opts] + * @param {boolean} [opts.raw] + * @param {boolean} [opts.json] + * @param {boolean} [opts.shards] + * @param {boolean} [opts.plainTree] + * @returns {string} + */ +export function uploadListResponseToString(res, opts = {}) { + if (opts.json) { + return res.results + .map(({ root, shards }) => dagJSON.stringify({ root, shards })) + .join('\n') + } else if (opts.shards) { + return res.results + .map(({ root, shards }) => { + const treeBuilder = opts.plainTree ? tree.plain : tree + return treeBuilder({ + label: root.toString(), + nodes: [ + { + label: 'shards', + leaf: shards?.map((s) => s.toString()), + }, + ], + }) + }) + .join('\n') + } else { + return res.results.map(({ root }) => root.toString()).join('\n') + } +} + +/** + * @param {BlobListSuccess} res + * @param {object} [opts] + * @param {boolean} [opts.raw] + * @param {boolean} [opts.json] + * @returns {string} + */ +export function blobListResponseToString(res, opts = {}) { + if (opts.json) { + return res.results.map(({ blob }) => dagJSON.stringify({ blob })).join('\n') + } else { + return res.results + .map(({ blob }) => { + const digest = Digest.decode(blob.digest) + const cid = Link.create(raw.code, digest) + return `${base58btc.encode(digest.bytes)} (${cid})` + }) + .join('\n') + } +} + +/** + * @param {FilecoinInfoSuccess} res + * @param {object} [opts] + * @param {boolean} [opts.raw] + * @param {boolean} [opts.json] + */ +export function filecoinInfoToString(res, opts = {}) { + if (opts.json) { + return res.deals + .map((deal) => + dagJSON.stringify({ + aggregate: deal.aggregate.toString(), + provider: deal.provider, + dealId: deal.aux.dataSource.dealID, + inclusion: res.aggregates.find( + (a) => a.aggregate.toString() === deal.aggregate.toString() + )?.inclusion, + }) + ) + .join('\n') + } else { + if (!res.deals.length) { + return ` + Piece CID: ${res.piece.toString()} + Deals: Piece being aggregated and offered for deal... + ` + } + // not showing inclusion proof as it would just be bytes + return ` + Piece CID: ${res.piece.toString()} + Deals: ${res.deals + .map( + (deal) => ` + Aggregate: ${deal.aggregate.toString()} + Provider: ${deal.provider} + Deal ID: ${deal.aux.dataSource.dealID} + ` + ) + .join('')} + ` + } +} + +/** + * Return validated CARLink or undefined + * + * @param {AnyLink} cid + */ +export function asCarLink(cid) { + if (cid.version === 1 && cid.code === CAR.codec.code) { + return /** @type {CARLink} */ (cid) + } +} + +/** + * Return validated CARLink type or exit the process with an error code and message + * + * @param {string} cidStr + */ +export function parseCarLink(cidStr) { + try { + return asCarLink(Link.parse(cidStr.trim())) + } catch { + return undefined + } +} + +/** @param {string|number|Date} now */ +const startOfMonth = (now) => { + const d = new Date(now) + d.setUTCDate(1) + d.setUTCHours(0) + d.setUTCMinutes(0) + d.setUTCSeconds(0) + d.setUTCMilliseconds(0) + return d +} + +/** @param {string|number|Date} now */ +export const startOfLastMonth = (now) => { + const d = startOfMonth(now) + d.setUTCMonth(d.getUTCMonth() - 1) + return d +} + +/** @param {ReadableStream} source */ +export const streamToBlob = async (source) => { + const chunks = /** @type {Uint8Array[]} */ ([]) + await source.pipeTo( + new WritableStream({ + write: (chunk) => { + chunks.push(chunk) + }, + }) + ) + return new Blob(chunks) +} diff --git a/packages/cli/package.json b/packages/cli/package.json new file mode 100644 index 000000000..98af213e3 --- /dev/null +++ b/packages/cli/package.json @@ -0,0 +1,100 @@ +{ + "name": "@storacha/cli", + "type": "module", + "version": "1.1.1", + "license": "Apache-2.0 OR MIT", + "description": "Command Line Interface to the Storacha Network", + "bin": { + "storacha": "bin.js" + }, + "scripts": { + "lint": "eslint '**/*.{js,ts}'", + "lint:fix": "eslint --fix '**/*.{js,ts}'", + "check": "tsc --build", + "format": "prettier --write '**/*.{js,ts,yml,json}' --ignore-path .gitignore", + "test": "entail **/*.spec.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/storacha/upload-service.git", + "directory": "packages/cli" + }, + "keywords": [ + "storacha", + "web3", + "storage", + "upload", + "cli" + ], + "bugs": { + "url": "https://github.com/storacha/upload-service/issues" + }, + "homepage": "https://github.com/storacha/upload-service#readme", + "devDependencies": { + "@storacha/capabilities": "workspace:^", + "@storacha/eslint-config": "workspace:^", + "@storacha/upload-api": "workspace:^", + "@types/update-notifier": "^6.0.5", + "@ucanto/interface": "^10.1.1", + "@ucanto/principal": "^9.0.2", + "@ucanto/server": "^10.1.0", + "@web-std/blob": "^3.0.5", + "@web3-storage/sigv4": "^1.0.2", + "entail": "^2.1.1", + "multiformats": "^13.1.1", + "npm-run-all": "^4.1.5", + "prettier": "^3.0.3", + "typescript": "^5.2.2" + }, + "dependencies": { + "@inquirer/core": "^5.1.1", + "@inquirer/prompts": "^3.3.0", + "@ipld/car": "^5.2.4", + "@ipld/dag-json": "^10.1.5", + "@ipld/dag-ucan": "^3.4.5", + "@storacha/access": "workspace:^", + "@storacha/client": "workspace:^", + "@storacha/did-mailto": "workspace:^", + "@ucanto/client": "^9.0.1", + "@ucanto/core": "^10.2.1", + "@ucanto/transport": "^9.1.1", + "@web3-storage/content-claims": "^5.1.3", + "@web3-storage/data-segment": "^5.0.0", + "ansi-escapes": "^6.2.0", + "chalk": "^5.3.0", + "crypto-random-string": "^5.0.0", + "files-from-path": "^1.0.4", + "fr32-sha2-256-trunc254-padded-binary-tree-multihash": "^3.3.0", + "open": "^9.1.0", + "ora": "^7.0.1", + "pretty-tree": "^1.0.0", + "s-ago": "^2.2.0", + "sade": "^1.8.1", + "update-notifier": "^7.0.0" + }, + "eslintConfig": { + "extends": [ + "@storacha/eslint-config" + ], + "parserOptions": { + "project": "./tsconfig.json" + }, + "env": { + "es2022": true, + "mocha": true, + "browser": true, + "node": true + }, + "ignorePatterns": [ + "dist", + "coverage", + "api.js" + ] + }, + "prettier": { + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true + } +} diff --git a/packages/cli/space.js b/packages/cli/space.js new file mode 100644 index 000000000..e191986d5 --- /dev/null +++ b/packages/cli/space.js @@ -0,0 +1,440 @@ +import * as W3Space from '@storacha/client/space' +import * as W3Account from '@storacha/client/account' +import * as UcantoClient from '@ucanto/client' +import { HTTP } from '@ucanto/transport' +import * as CAR from '@ucanto/transport/car' +import { getClient } from './lib.js' +import process from 'node:process' +import * as DIDMailto from '@storacha/did-mailto' +import * as Account from './account.js' +import { SpaceDID } from '@storacha/capabilities/utils' +import ora from 'ora' +import { select, input } from '@inquirer/prompts' +import { mnemonic } from './dialog.js' +import { API } from '@ucanto/core' +import * as Result from '@storacha/client/result' + +/** + * @typedef {object} CreateOptions + * @property {false} [recovery] + * @property {false} [caution] + * @property {DIDMailto.EmailAddress|false} [customer] + * @property {string|false} [account] + * @property {Array<{id: import('@ucanto/interface').DID, serviceEndpoint: string}>} [authorizeGatewayServices] - The DID Key or DID Web and URL of the Gateway to authorize to serve content from the created space. + * @property {boolean} [skipGatewayAuthorization] - Whether to skip the Gateway authorization. It means that the content of the space will not be served by any Gateway. + * + * @param {string|undefined} name + * @param {CreateOptions} options + */ +export const create = async (name, options) => { + const client = await getClient() + const spaces = client.spaces() + + let space + if (options.skipGatewayAuthorization === true) { + space = await client.createSpace(await chooseName(name ?? '', spaces), { + skipGatewayAuthorization: true, + }) + } else { + const gateways = options.authorizeGatewayServices ?? [] + const connections = gateways.map(({ id, serviceEndpoint }) => { + /** @type {UcantoClient.ConnectionView} */ + const connection = UcantoClient.connect({ + id: { + did: () => id, + }, + codec: CAR.outbound, + channel: HTTP.open({ url: new URL(serviceEndpoint) }), + }) + return connection + }) + space = await client.createSpace(await chooseName(name ?? '', spaces), { + authorizeGatewayServices: connections, + }) + } + + // Unless use opted-out from paper key recovery, we go through the flow + if (options.recovery !== false) { + const recovery = await setupRecovery(space, options) + if (recovery == null) { + console.log( + '⚠️ Aborting, if you want to create space without recovery option pass --no-recovery flag' + ) + process.exit(1) + } + } + + if (options.customer !== false) { + console.log('🏗️ To serve this space we need to set a billing account') + const setup = await setupBilling(client, { + customer: options.customer, + space: space.did(), + message: '🚜 Setting a billing account', + }) + + if (setup.error) { + if (setup.error.reason === 'abort') { + console.log( + '⏭️ Skipped billing setup. You can do it later using `storacha space provision`' + ) + } else { + console.error( + '⚠️ Failed to to set billing account. You can retry using `storacha space provision`' + ) + console.error(setup.error.cause.message) + } + } else { + console.log(`✨ Billing account is set`) + } + } + + // Authorize this client to allow them to use this space. + // ⚠️ This is a temporary solution until we solve the account sync problem + // after which we will simply delegate to the account. + const authorization = await space.createAuthorization(client) + await client.addSpace(authorization) + // set this space as the current default space + await client.setCurrentSpace(space.did()) + + // Unless user opted-out we go through an account authorization flow + if (options.account !== false) { + console.log( + `⛓️ To manage space across devices we need to authorize an account` + ) + + const account = options.account + ? await useAccount(client, { email: options.account }) + : await selectAccount(client) + + if (account) { + const spinner = ora(`📩 Authorizing ${account.toEmail()}`).start() + const recovery = await space.createRecovery(account.did()) + + const result = await client.capability.access.delegate({ + space: space.did(), + delegations: [recovery], + }) + spinner.stop() + + if (result.ok) { + console.log(`✨ Account is authorized`) + } else { + console.error( + `⚠️ Failed to authorize account. You can still manage space using "paper key"` + ) + console.error(result.error) + } + } else { + console.log( + `⏭️ Skip account authorization. You can still can manage space using "paper key"` + ) + } + } + + console.log(`⁂ Space created: ${space.did()}`) + + return space +} + +/** + * @param {import('@storacha/client').Client} client + * @param {object} options + * @param {import('@storacha/client/types').SpaceDID} options.space + * @param {DIDMailto.EmailAddress} [options.customer] + * @param {string} [options.message] + * @param {string} [options.waitMessage] + * @returns {Promise>} + */ +const setupBilling = async ( + client, + { + customer, + space, + message = 'Setting up a billing account', + waitMessage = 'Waiting for payment plan to be selected', + } +) => { + const account = customer + ? await useAccount(client, { email: customer }) + : await selectAccount(client) + + if (account) { + const spinner = ora(waitMessage).start() + + let plan = null + while (!plan) { + const result = await account.plan.get() + + if (result.ok) { + plan = result.ok + } else { + await new Promise((resolve) => setTimeout(resolve, 1000)) + } + } + + spinner.text = message + + const result = await account.provision(space) + + spinner.stop() + if (result.error) { + return { error: { reason: 'error', cause: result.error } } + } else { + return { ok: {} } + } + } else { + return { error: { reason: 'abort' } } + } +} + +/** + * @typedef {object} ProvisionOptions + * @property {DIDMailto.EmailAddress} [customer] + * @property {string} [coupon] + * @property {string} [provider] + * @property {string} [password] + * + * @param {string} name + * @param {ProvisionOptions} options + */ +export const provision = async (name = '', options = {}) => { + const client = await getClient() + const space = chooseSpace(client, { name }) + if (!space) { + console.log( + `You do not appear to have a space, you can create one by running "w3 space create"` + ) + process.exit(1) + } + + if (options.coupon) { + const { ok: bytes, error: fetchError } = await fetch(options.coupon) + .then((response) => response.arrayBuffer()) + .then((buffer) => Result.ok(new Uint8Array(buffer))) + .catch((error) => Result.error(/** @type {Error} */ (error))) + + if (fetchError) { + console.error(`Failed to fetch coupon from ${options.coupon}`) + process.exit(1) + } + + const { ok: access, error: couponError } = await client.coupon + .redeem(bytes, options) + .then(Result.ok, Result.error) + + if (!access) { + console.error(`Failed to redeem coupon: ${couponError.message}}`) + process.exit(1) + } + + const result = await W3Space.provision( + { did: () => space }, + { + proofs: access.proofs, + agent: client.agent, + } + ) + + if (result.error) { + console.log(`Failed to provision space: ${result.error.message}`) + process.exit(1) + } + } else { + const result = await setupBilling(client, { + customer: options.customer, + space, + }) + + if (result.error) { + console.error( + `⚠️ Failed to set up billing account,\n ${ + Object(result.error).message ?? '' + }` + ) + process.exit(1) + } + } + + console.log(`✨ Billing account is set`) +} + +/** + * @typedef {import('@storacha/client/types').SpaceDID} SpaceDID + * + * @param {import('@storacha/client').Client} client + * @param {object} options + * @param {string} options.name + * @returns {SpaceDID|undefined} + */ +const chooseSpace = (client, { name }) => { + if (name) { + const result = SpaceDID.read(name) + if (result.ok) { + return result.ok + } + + const space = client.spaces().find((space) => space.name === name) + if (space) { + return /** @type {SpaceDID} */ (space.did()) + } + } + + return /** @type {SpaceDID|undefined} */ (client.currentSpace()?.did()) +} + +/** + * + * @param {W3Space.Model} space + * @param {CreateOptions} options + */ +export const setupEmailRecovery = async (space, options = {}) => {} + +/** + * @param {string} email + * @returns {{ok: DIDMailto.EmailAddress, error?:void}|{ok?:void, error: Error}} + */ +const parseEmail = (email) => { + try { + return { ok: DIDMailto.email(email) } + } catch (cause) { + return { error: /** @type {Error} */ (cause) } + } +} + +/** + * @param {W3Space.OwnedSpace} space + * @param {CreateOptions} options + */ +export const setupRecovery = async (space, options = {}) => { + const recoveryKey = W3Space.toMnemonic(space) + + if (options.caution === false) { + console.log(formatRecoveryInstruction(recoveryKey)) + return space + } else { + const verified = await mnemonic({ + secret: recoveryKey.split(/\s+/g), + message: + 'You need to save the following secret recovery key somewhere safe! For example write it down on a piece of paper and put it inside your favorite book.', + revealMessage: + '🤫 Make sure no one is eavesdropping and hit enter to reveal the key', + submitMessage: '📝 Once you have saved the key hit enter to continue', + validateMessage: + '🔒 Please type or paste your recovery key to make sure it is correct', + exitMessage: '🔐 Secret recovery key is correct!', + }).catch(() => null) + + return verified ? space : null + } +} + +/** + * @param {string} key + */ +const formatRecoveryInstruction = (key) => + `🔑 You need to save following secret recovery key somewhere safe! For example write it down on a piece of paper and put it inside your favorite book. + + ${key} + +` + +/** + * @param {string} name + * @param {{name:string}[]} spaces + * @returns {Promise} + */ +const chooseName = async (name, spaces) => { + const space = spaces.find((space) => String(space.name) === name) + const message = + name === '' + ? 'What would you like to call this space?' + : space + ? `Name "${space.name}" is already taken, please choose a different one` + : null + + if (message == null) { + return name + } else { + return await input({ + message, + }) + } +} + +/** + * @param {import('@storacha/client').Client} client + * @param {{email?:string}} options + */ +export const pickAccount = async (client, { email }) => + email ? await useAccount(client, { email }) : await selectAccount(client) + +/** + * @param {import('@storacha/client').Client} client + * @param {{email?:string}} options + */ +export const useAccount = (client, { email }) => { + const accounts = Object.values(W3Account.list(client)) + const account = accounts.find((account) => account.toEmail() === email) + + if (!account) { + console.error( + `Agent is not authorized by ${email}, please login with it first` + ) + return null + } + + return account +} + +/** + * @param {import('@storacha/client').Client} client + */ +export const selectAccount = async (client) => { + const accounts = Object.values(W3Account.list(client)) + + // If we do not have any accounts yet we take user through setup flow + if (accounts.length === 0) { + return setupAccount(client) + } + // If we have only one account we use it + else if (accounts.length === 1) { + return accounts[0] + } + // Otherwise we ask user to choose one + else { + return chooseAccount(accounts) + } +} + +/** + * @param {import('@storacha/client').Client} client + */ +export const setupAccount = async (client) => { + const email = await input({ + message: `📧 Please enter an email address to setup an account`, + validate: (input) => parseEmail(input).ok != null, + }).catch(() => null) + + return email + ? await Account.loginWithClient( + /** @type {DIDMailto.EmailAddress} */ (email), + client + ) + : null +} + +/** + * @param {Account.View[]} accounts + * @returns {Promise} + */ +export const chooseAccount = async (accounts) => { + const account = await select({ + message: 'Please choose an account you would like to use', + choices: accounts.map((account) => ({ + name: account.toEmail(), + value: account, + })), + }).catch(() => null) + + return account +} diff --git a/packages/cli/test/bin.spec.js b/packages/cli/test/bin.spec.js new file mode 100644 index 000000000..471571c81 --- /dev/null +++ b/packages/cli/test/bin.spec.js @@ -0,0 +1,1537 @@ +import fs from 'fs' +import os from 'os' +import path from 'path' +import * as Signer from '@ucanto/principal/ed25519' +import { importDAG } from '@ucanto/core/delegation' +import { parseLink } from '@ucanto/server' +import * as DID from '@ipld/dag-ucan/did' +import * as dagJSON from '@ipld/dag-json' +import { SpaceDID } from '@storacha/capabilities/utils' +import { CarReader } from '@ipld/car' +import { test } from './helpers/context.js' +import * as Test from './helpers/context.js' +import { pattern, match } from './helpers/util.js' +import * as Command from './helpers/process.js' +import { Absentee, ed25519 } from '@ucanto/principal' +import * as DIDMailto from '@storacha/did-mailto' +import { UCAN, Provider } from '@storacha/capabilities' +import * as ED25519 from '@ucanto/principal/ed25519' +import { sha256, delegate } from '@ucanto/core' +import * as Result from '@storacha/client/result' +import * as Link from 'multiformats/link' +import { base64 } from 'multiformats/bases/base64' +import { base58btc } from 'multiformats/bases/base58' +import * as Digest from 'multiformats/hashes/digest' + +const storacha = Command.create('./bin.js') + +export const testStoracha = { + storacha: test(async (assert, { env }) => { + const { output } = await storacha.env(env.alice).join() + + assert.match(output, /Available Commands/) + }), + + 'storacha nosuchcmd': test(async (assert, context) => { + const { status, output } = await storacha + .args(['nosuchcmd']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(status.code, 1) + assert.match(output, /Invalid command: nosuch/) + }), + + 'storacha --version': test(async (assert, context) => { + const { output, status } = await storacha.args(['--version']).join() + + assert.equal(status.code, 0) + assert.match(output, /storacha, \d.\d.\d/) + }), + + 'storacha whoami': test(async (assert) => { + const { output } = await storacha.args(['whoami']).join() + + assert.match(output, /^did:key:/) + }), +} + +export const testAccount = { + 'storacha account ls': test(async (assert, context) => { + const { output } = await storacha + .env(context.env.alice) + .args(['account ls']) + .join() + + assert.match(output, /has not been authorized yet/) + }), + + 'storacha login': test(async (assert, context) => { + const login = storacha + .args(['login', 'alice@web.mail']) + .env(context.env.alice) + .fork() + + const line = await login.error.lines().take().text() + assert.match(line, /please click the link sent/) + + // receive authorization request + const mail = await context.mail.take() + + // confirm authorization + await context.grantAccess(mail) + + const message = await login.output.text() + + assert.match(message ?? '', /authorized by did:mailto:web.mail:alice/) + }), + + 'storacha account list': test(async (assert, context) => { + await login(context) + + const { output } = await storacha + .env(context.env.alice) + .args(['account list']) + .join() + + assert.match(output, /did:mailto:web.mail:alice/) + }), +} + +export const testSpace = { + 'storacha space create': test(async (assert, context) => { + const command = storacha + .args(['space', 'create', '--no-gateway-authorization']) + .env(context.env.alice) + .fork() + + const line = await command.output.take(1).text() + + assert.match(line, /What would you like to call this space/) + + await command.terminate().join().catch() + }), + + 'storacha space create home': test(async (assert, context) => { + const create = storacha + .args(['space', 'create', 'home', '--no-gateway-authorization']) + .env(context.env.alice) + .fork() + + const message = await create.output.take(1).text() + + const [prefix, key, suffix] = message.split('\n\n') + + assert.match(prefix, /secret recovery key/) + assert.match(suffix, /hit enter to reveal the key/) + + const secret = key.replaceAll(/[\s\n]+/g, '') + assert.equal(secret, '█'.repeat(secret.length), 'key is concealed') + + assert.ok(secret.length > 60, 'there are several words') + + await create.terminate().join().catch() + }), + + 'storacha space create home --no-caution': test(async (assert, context) => { + const create = storacha + .args([ + 'space', + 'create', + 'home', + '--no-caution', + '--no-gateway-authorization', + ]) + .env(context.env.alice) + .fork() + + const message = await create.output.lines().take(6).text() + + const lines = message.split('\n').filter((line) => line.trim() !== '') + const [prefix, key, suffix] = lines + + assert.match(prefix, /secret recovery key/) + assert.match(suffix, /billing account/, 'no heads up') + const words = key.trim().split(' ') + assert.ok( + words.every((word) => [...word].every((letter) => letter !== '█')), + 'key is revealed' + ) + assert.ok(words.length > 20, 'there are several words') + + await create.terminate().join().catch() + }), + + 'storacha space create my-space --no-recovery': test( + async (assert, context) => { + const create = storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-gateway-authorization', + ]) + .env(context.env.alice) + .fork() + + const line = await create.output.lines().take().text() + + assert.match(line, /billing account/, 'no paper recovery') + + await create.terminate().join().catch() + } + ), + + 'storacha space create my-space --no-recovery (logged-in)': test( + async (assert, context) => { + await login(context) + + await selectPlan(context) + + const create = storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-gateway-authorization', + ]) + .env(context.env.alice) + .fork() + + const lines = await create.output.lines().take(2).text() + + assert.match(lines, /billing account is set/i) + + await create.terminate().join().catch() + } + ), + + 'storacha space create my-space --no-recovery (multiple accounts)': test( + async (assert, context) => { + await login(context, { email: 'alice@web.mail' }) + await login(context, { email: 'alice@email.me' }) + + const create = storacha + .args([ + 'space', + 'create', + 'my-space', + '--no-recovery', + '--no-gateway-authorization', + ]) + .env(context.env.alice) + .fork() + + const output = await create.output.take(2).text() + + assert.match( + output, + /choose an account you would like to use/, + 'choose account' + ) + + assert.ok(output.includes('alice@web.mail')) + assert.ok(output.includes('alice@email.me')) + + create.terminate() + } + ), + + 'storacha space create void --skip-paper --provision-as unknown@web.mail --skip-email': + test(async (assert, context) => { + const { output, error } = await storacha + .env(context.env.alice) + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--customer', + 'unknown@web.mail', + '--no-account', + '--no-gateway-authorization', + ]) + .join() + .catch() + + assert.match(output, /billing account/) + assert.match(output, /Skipped billing setup/) + assert.match(error, /not authorized by unknown@web\.mail/) + }), + + 'storacha space create home --no-recovery --customer alice@web.mail --no-account': + test(async (assert, context) => { + await login(context, { email: 'alice@web.mail' }) + await selectPlan(context) + + const create = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-gateway-authorization', + '--customer', + 'alice@web.mail', + '--no-account', + ]) + .env(context.env.alice) + .join() + + assert.match(create.output, /Billing account is set/) + + const info = await storacha + .args(['space', 'info']) + .env(context.env.alice) + .join() + + assert.match(info.output, /Providers: did:web:/) + }), + + 'storacha space create home --no-recovery --customer alice@web.mail --account alice@web.mail': + test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const { output } = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-gateway-authorization', + '--customer', + email, + '--account', + email, + ]) + .env(context.env.alice) + .join() + + assert.match(output, /account is authorized/i) + + const result = await context.delegationsStorage.find({ + audience: DIDMailto.fromEmail(email), + }) + + assert.ok( + result.ok?.find((d) => d.capabilities[0].can === '*'), + 'account has been delegated access to the space' + ) + }), + + 'storacha space create home --no-recovery (blocks until plan is selected)': + test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + + context.plansStorage.get = async () => { + return { + ok: { product: 'did:web:free.web3.storage', updatedAt: 'now' }, + } + } + + const { output, error } = await storacha + .env(context.env.alice) + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-gateway-authorization', + ]) + .join() + + assert.match(output, /billing account is set/i) + assert.match(error, /wait.*plan.*select/i) + }), + + 'storacha space create home --no-recovery --customer alice@web.mail --account alice@web.mail --authorize-gateway-services': + test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const serverId = context.connection.id + const serverURL = context.serverURL + + const { output } = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--customer', + email, + '--account', + email, + '--authorize-gateway-services', + `[{"id":"${serverId}","serviceEndpoint":"${serverURL}"}]`, + ]) + .env(context.env.alice) + .join() + + assert.match(output, /account is authorized/i) + + const result = await context.delegationsStorage.find({ + audience: DIDMailto.fromEmail(email), + }) + + assert.ok( + result.ok?.find((d) => d.capabilities[0].can === '*'), + 'account has been delegated access to the space' + ) + }), + + 'storacha space add': test(async (assert, context) => { + const { env } = context + + const spaceDID = await loginAndCreateSpace(context, { env: env.alice }) + + const whosBob = await storacha.args(['whoami']).env(env.bob).join() + + const bobDID = SpaceDID.from(whosBob.output.trim()) + + const proofPath = path.join( + os.tmpdir(), + `storacha-cli-test-delegation-${Date.now()}` + ) + + await storacha + .args([ + 'delegation', + 'create', + bobDID, + '-c', + 'store/*', + 'upload/*', + '--output', + proofPath, + ]) + .env(env.alice) + .join() + + const listNone = await storacha.args(['space', 'ls']).env(env.bob).join() + assert.ok(!listNone.output.includes(spaceDID)) + + const add = await storacha + .args(['space', 'add', proofPath]) + .env(env.bob) + .join() + assert.equal(add.output.trim(), spaceDID) + + const listSome = await storacha.args(['space', 'ls']).env(env.bob).join() + assert.ok(listSome.output.includes(spaceDID)) + }), + + 'storacha space add `base64 proof car`': test(async (assert, context) => { + const { env } = context + const spaceDID = await loginAndCreateSpace(context, { env: env.alice }) + const whosBob = await storacha.args(['whoami']).env(env.bob).join() + const bobDID = SpaceDID.from(whosBob.output.trim()) + const res = await storacha + .args([ + 'delegation', + 'create', + bobDID, + '-c', + 'store/*', + 'upload/*', + '--base64', + ]) + .env(env.alice) + .join() + + const listNone = await storacha.args(['space', 'ls']).env(env.bob).join() + assert.ok(!listNone.output.includes(spaceDID)) + + const add = await storacha + .args(['space', 'add', res.output]) + .env(env.bob) + .join() + assert.equal(add.output.trim(), spaceDID) + + const listSome = await storacha.args(['space', 'ls']).env(env.bob).join() + assert.ok(listSome.output.includes(spaceDID)) + }), + + 'storacha space add invalid/path': test(async (assert, context) => { + const fail = await storacha + .args(['space', 'add', 'djcvbii']) + .env(context.env.alice) + .join() + .catch() + + assert.ok(!fail.status.success()) + assert.match(fail.error, /failed to read proof/) + }), + + 'storacha space add not-a-car.gif': test(async (assert, context) => { + const fail = await storacha + .args(['space', 'add', './package.json']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(fail.status.success(), false) + assert.match(fail.error, /failed to parse proof/) + }), + + 'storacha space add empty.car': test(async (assert, context) => { + const fail = await storacha + .args(['space', 'add', './test/fixtures/empty.car']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(fail.status.success(), false) + assert.match(fail.error, /failed to import proof/) + }), + + 'storacha space ls': test(async (assert, context) => { + const emptyList = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + + const spaceDID = await loginAndCreateSpace(context) + + const spaceList = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + + assert.ok(!emptyList.output.includes(spaceDID)) + assert.ok(spaceList.output.includes(spaceDID)) + }), + + 'storacha space use': test(async (assert, context) => { + const spaceDID = await loginAndCreateSpace(context, { + env: context.env.alice, + }) + + const listDefault = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + assert.ok(listDefault.output.includes(`* ${spaceDID}`)) + + const spaceName = 'laundry' + + const newSpaceDID = await createSpace(context, { name: spaceName }) + + const listNewDefault = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + + assert.equal( + listNewDefault.output.includes(`* ${spaceDID}`), + false, + 'old space is not default' + ) + assert.equal( + listNewDefault.output.includes(`* ${newSpaceDID}`), + true, + 'new space is the default' + ) + + assert.equal( + listNewDefault.output.includes(spaceDID), + true, + 'old space is still listed' + ) + + await storacha + .args(['space', 'use', spaceDID]) + .env(context.env.alice) + .join() + const listSetDefault = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + + assert.equal( + listSetDefault.output.includes(`* ${spaceDID}`), + true, + 'spaceDID is default' + ) + assert.equal( + listSetDefault.output.includes(`* ${newSpaceDID}`), + false, + 'new space is not default' + ) + + await storacha + .args(['space', 'use', spaceName]) + .env(context.env.alice) + .join() + const listNamedDefault = await storacha + .args(['space', 'ls']) + .env(context.env.alice) + .join() + + assert.equal(listNamedDefault.output.includes(`* ${spaceDID}`), false) + assert.equal(listNamedDefault.output.includes(`* ${newSpaceDID}`), true) + }), + + 'storacha space use did:key:unknown': test(async (assert, context) => { + const space = await Signer.generate() + + const useSpace = await storacha + .args(['space', 'use', space.did()]) + .env(context.env.alice) + .join() + .catch() + + assert.match(useSpace.error, /space not found/) + }), + + 'storacha space use notfound': test(async (assert, context) => { + const useSpace = await storacha + .args(['space', 'use', 'notfound']) + .env(context.env.alice) + .join() + .catch() + + assert.match(useSpace.error, /space not found/) + }), + + 'storacha space info': test(async (assert, context) => { + const spaceDID = await loginAndCreateSpace(context, { + customer: null, + }) + + /** @type {import('@storacha/client/types').DID<'web'>} */ + const providerDID = 'did:web:test.upload.storacha.network' + + const infoWithoutProvider = await storacha + .args(['space', 'info']) + .env(context.env.alice) + .join() + + assert.match( + infoWithoutProvider.output, + pattern`DID: ${spaceDID}\nProviders: .*none`, + 'space has no providers' + ) + + assert.match( + infoWithoutProvider.output, + pattern`Name: home`, + 'space name is set' + ) + + await Test.provisionSpace(context, { + space: spaceDID, + account: 'did:mailto:web.mail:alice', + provider: providerDID, + }) + + // wait 1 second so we don't get a cached receipt + await new Promise((resolve) => setTimeout(resolve, 1000)) + + const infoWithProvider = await storacha + .args(['space', 'info']) + .env(context.env.alice) + .join() + + assert.match( + infoWithProvider.output, + pattern`DID: ${spaceDID}\nProviders: .*${providerDID}`, + 'added provider shows up in the space info' + ) + + const infoWithProviderJson = await storacha + .args(['space', 'info', '--json']) + .env(context.env.alice) + .join() + + assert.deepEqual(JSON.parse(infoWithProviderJson.output), { + did: spaceDID, + providers: [providerDID], + name: 'home', + }) + }), + + 'storacha space provision --coupon': test(async (assert, context) => { + const spaceDID = await loginAndCreateSpace(context, { customer: null }) + + assert.deepEqual( + await context.provisionsStorage.getStorageProviders(spaceDID), + { ok: [] }, + 'space has no providers yet' + ) + + const archive = await createCustomerSession(context) + context.router['/proof.car'] = async () => { + return { + status: 200, + headers: { 'content-type': 'application/car' }, + body: archive, + } + } + + const url = new URL('/proof.car', context.serverURL) + const provision = await storacha + .env(context.env.alice) + .args(['space', 'provision', '--coupon', url.href]) + .join() + + assert.match(provision.output, /Billing account is set/) + + const info = await storacha + .env(context.env.alice) + .args(['space', 'info']) + .join() + + assert.match( + info.output, + pattern`Providers: ${context.service.did()}`, + 'space got provisioned' + ) + }), +} + +export const testStorachaUp = { + 'storacha up': test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const create = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-account', + '--no-gateway-authorization', + '--customer', + email, + ]) + .env(context.env.alice) + .join() + + assert.ok(create.status.success()) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafybeiajdopsmspomlrpaohtzo5sdnpknbolqjpde6huzrsejqmvijrcea/ + ) + assert.match(up.error, /Stored 1 file/) + }), + + 'storacha up --no-wrap': test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const create = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-account', + '--no-gateway-authorization', + '--customer', + email, + ]) + .env(context.env.alice) + .join() + + assert.ok(create.status.success()) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg', '--no-wrap']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafkreiajkbmpugz75eg2tmocmp3e33sg5kuyq2amzngslahgn6ltmqxxfa/ + ) + assert.match(up.error, /Stored 1 file/) + }), + + 'storacha up --wrap false': test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + + const create = await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-account', + '--no-gateway-authorization', + '--customer', + email, + ]) + .env(context.env.alice) + .join() + + assert.ok(create.status.success()) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg', '--wrap', 'false']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafkreiajkbmpugz75eg2tmocmp3e33sg5kuyq2amzngslahgn6ltmqxxfa/ + ) + assert.match(up.error, /Stored 1 file/) + }), + + 'storacha up --car': test(async (assert, context) => { + const email = 'alice@web.mail' + await login(context, { email }) + await selectPlan(context, { email }) + await storacha + .args([ + 'space', + 'create', + 'home', + '--no-recovery', + '--no-account', + '--no-gateway-authorization', + '--customer', + email, + ]) + .env(context.env.alice) + .join() + + const up = await storacha + .args(['up', '--car', 'test/fixtures/pinpie.car']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafkreiajkbmpugz75eg2tmocmp3e33sg5kuyq2amzngslahgn6ltmqxxfa/ + ) + assert.match(up.error, /Stored 1 file/) + }), + + 'storacha ls': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const list0 = await storacha.args(['ls']).env(context.env.alice).join() + assert.match(list0.output, /No uploads in space/) + + await storacha + .args(['up', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + // wait a second for invocation to get a different expiry + await new Promise((resolve) => setTimeout(resolve, 1000)) + + const list1 = await storacha + .args(['ls', '--json']) + .env(context.env.alice) + .join() + + assert.ok(dagJSON.parse(list1.output)) + }), + + 'storacha remove': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafybeiajdopsmspomlrpaohtzo5sdnpknbolqjpde6huzrsejqmvijrcea/ + ) + + const rm = await storacha + .args([ + 'rm', + 'bafybeiajdopsmspomlrpaohtzo5sdnpknbolqjpde6huzrsejqmvijrcea', + ]) + .env(context.env.alice) + .join() + .catch() + + assert.equal(rm.status.code, 0) + assert.equal(rm.output, '') + }), + + 'storacha remove - no such upload': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const rm = await storacha + .args([ + 'rm', + 'bafybeih2k7ughhfwedltjviunmn3esueijz34snyay77zmsml5w24tqamm', + '--shards', + ]) + .env(context.env.alice) + .join() + .catch() + + assert.equal(rm.status.code, 1) + assert.match(rm.error, /not found/) + }), +} + +export const testDelegation = { + 'storacha delegation create -c store/* --output file/path': test( + async (assert, context) => { + const env = context.env.alice + const { bob } = Test + + const spaceDID = await loginAndCreateSpace(context) + + const proofPath = path.join( + os.tmpdir(), + `storacha-cli-test-delegation-${Date.now()}` + ) + + await storacha + .args([ + 'delegation', + 'create', + bob.did(), + '-c', + 'store/*', + '--output', + proofPath, + ]) + .env(env) + .join() + + const reader = await CarReader.fromIterable( + fs.createReadStream(proofPath) + ) + const blocks = [] + for await (const block of reader.blocks()) { + blocks.push(block) + } + + // @ts-expect-error + const delegation = importDAG(blocks) + assert.equal(delegation.audience.did(), bob.did()) + assert.equal(delegation.capabilities[0].can, 'store/*') + assert.equal(delegation.capabilities[0].with, spaceDID) + } + ), + + 'storacha delegation create': test(async (assert, context) => { + const env = context.env.alice + const { bob } = Test + await loginAndCreateSpace(context) + + const delegate = await storacha + .args(['delegation', 'create', bob.did()]) + .env(env) + .join() + + // TODO: Test output after we switch to Delegation.archive() / Delegation.extract() + assert.equal(delegate.status.success(), true) + }), + + 'storacha delegation create -c store/add -c upload/add --base64': test( + async (assert, context) => { + const env = context.env.alice + const { bob } = Test + const spaceDID = await loginAndCreateSpace(context) + const res = await storacha + .args([ + 'delegation', + 'create', + bob.did(), + '-c', + 'store/add', + '-c', + 'upload/add', + '--base64', + ]) + .env(env) + .join() + + assert.equal(res.status.success(), true) + + const identityCid = parseLink(res.output, base64) + const reader = await CarReader.fromBytes(identityCid.multihash.digest) + const blocks = [] + for await (const block of reader.blocks()) { + blocks.push(block) + } + + // @ts-expect-error + const delegation = importDAG(blocks) + assert.equal(delegation.audience.did(), bob.did()) + assert.equal(delegation.capabilities[0].can, 'store/add') + assert.equal(delegation.capabilities[0].with, spaceDID) + assert.equal(delegation.capabilities[1].can, 'upload/add') + assert.equal(delegation.capabilities[1].with, spaceDID) + } + ), + + 'storacha delegation ls --json': test(async (assert, context) => { + const { mallory } = Test + + const spaceDID = await loginAndCreateSpace(context) + + // delegate to mallory + await storacha + .args(['delegation', 'create', mallory.did(), '-c', 'store/*']) + .env(context.env.alice) + .join() + + const list = await storacha + .args(['delegation', 'ls', '--json']) + .env(context.env.alice) + .join() + + const data = JSON.parse(list.output) + + assert.equal(data.audience, mallory.did()) + assert.equal(data.capabilities.length, 1) + assert.equal(data.capabilities[0].with, spaceDID) + assert.equal(data.capabilities[0].can, 'store/*') + }), + + 'storacha delegation revoke': test(async (assert, context) => { + const env = context.env.alice + const { mallory } = Test + await loginAndCreateSpace(context) + + const delegationPath = `${os.tmpdir()}/delegation-${Date.now()}.ucan` + await storacha + .args([ + 'delegation', + 'create', + mallory.did(), + '-c', + 'store/*', + 'upload/*', + '-o', + delegationPath, + ]) + .env(env) + .join() + + const list = await storacha + .args(['delegation', 'ls', '--json']) + .env(context.env.alice) + .join() + const { cid } = JSON.parse(list.output) + + // alice should be able to revoke the delegation she just created + const revoke = await storacha + .args(['delegation', 'revoke', cid]) + .env(context.env.alice) + .join() + + assert.match(revoke.output, pattern`delegation ${cid} revoked`) + + await loginAndCreateSpace(context, { + env: context.env.bob, + customer: 'bob@super.host', + }) + + // bob should not be able to because he doesn't have a copy of the delegation + const fail = await storacha + .args(['delegation', 'revoke', cid]) + .env(context.env.bob) + .join() + .catch() + + assert.match( + fail.error, + pattern`Error: revoking ${cid}: could not find delegation ${cid}` + ) + + // but if bob passes the delegation manually, it should succeed - we don't + // validate that bob is able to issue the revocation, it simply won't apply + // if it's not legitimate + + const pass = await storacha + .args(['delegation', 'revoke', cid, '-p', delegationPath]) + .env(context.env.bob) + .join() + + assert.match(pass.output, pattern`delegation ${cid} revoked`) + }), +} + +export const testProof = { + 'storacha proof add': test(async (assert, context) => { + const { env } = context + + const spaceDID = await loginAndCreateSpace(context, { env: env.alice }) + const whoisbob = await storacha.args(['whoami']).env(env.bob).join() + const bobDID = DID.parse(whoisbob.output.trim()).did() + const proofPath = path.join( + os.tmpdir(), + `storacha-cli-test-delegation-${Date.now()}` + ) + + await storacha + .args([ + 'delegation', + 'create', + bobDID, + '-c', + 'store/*', + '--output', + proofPath, + ]) + .env(env.alice) + .join() + + const listNone = await storacha.args(['proof', 'ls']).env(env.bob).join() + assert.ok(!listNone.output.includes(spaceDID)) + + const addProof = await storacha + .args(['proof', 'add', proofPath]) + .env(env.bob) + .join() + + assert.ok(addProof.output.includes(`with: ${spaceDID}`)) + const listProof = await storacha.args(['proof', 'ls']).env(env.bob).join() + assert.ok(listProof.output.includes(spaceDID)) + }), + 'storacha proof add notfound': test(async (assert, context) => { + const proofAdd = await storacha + .args(['proof', 'add', 'djcvbii']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(proofAdd.status.success(), false) + assert.match(proofAdd.error, /failed to read proof/) + }), + 'storacha proof add not-car.json': test(async (assert, context) => { + const proofAdd = await storacha + .args(['proof', 'add', './package.json']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(proofAdd.status.success(), false) + assert.match(proofAdd.error, /failed to parse proof/) + }), + 'storacha proof add invalid.car': test(async (assert, context) => { + const proofAdd = await storacha + .args(['proof', 'add', './test/fixtures/empty.car']) + .env(context.env.alice) + .join() + .catch() + + assert.equal(proofAdd.status.success(), false) + assert.match(proofAdd.error, /failed to import proof/) + }), + 'storacha proof ls': test(async (assert, context) => { + const { env } = context + const spaceDID = await loginAndCreateSpace(context, { env: env.alice }) + const whoisalice = await storacha.args(['whoami']).env(env.alice).join() + const aliceDID = DID.parse(whoisalice.output.trim()).did() + + const whoisbob = await storacha.args(['whoami']).env(env.bob).join() + const bobDID = DID.parse(whoisbob.output.trim()).did() + + const proofPath = path.join( + os.tmpdir(), + `storacha-cli-test-proof-${Date.now()}` + ) + await storacha + .args([ + 'delegation', + 'create', + '-c', + 'store/*', + bobDID, + '--output', + proofPath, + ]) + .env(env.alice) + .join() + + await storacha.args(['space', 'add', proofPath]).env(env.bob).join() + + const proofList = await storacha + .args(['proof', 'ls', '--json']) + .env(env.bob) + .join() + const proofData = JSON.parse(proofList.output) + assert.equal(proofData.iss, aliceDID) + assert.equal(proofData.att.length, 1) + assert.equal(proofData.att[0].with, spaceDID) + assert.equal(proofData.att[0].can, 'store/*') + }), +} + +export const testBlob = { + 'storacha can blob add': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const { error } = await storacha + .args(['can', 'blob', 'add', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + assert.match(error, /Stored zQm/) + }), + + 'storacha can blob ls': test(async (assert, context) => { + await loginAndCreateSpace(context) + + await storacha + .args(['can', 'blob', 'add', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + const list = await storacha + .args(['can', 'blob', 'ls', '--json']) + .env(context.env.alice) + .join() + + assert.ok(dagJSON.parse(list.output)) + }), + + 'storacha can blob rm': test(async (assert, context) => { + await loginAndCreateSpace(context) + + await storacha + .args(['can', 'blob', 'add', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + const list = await storacha + .args(['can', 'blob', 'ls', '--json']) + .env(context.env.alice) + .join() + + const digest = Digest.decode(dagJSON.parse(list.output).blob.digest) + + const remove = await storacha + .args(['can', 'blob', 'rm', base58btc.encode(digest.bytes)]) + .env(context.env.alice) + .join() + + assert.match(remove.error, /Removed zQm/) + }), +} + +export const testCan = { + 'storacha can upload add': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const carPath = 'test/fixtures/pinpie.car' + const reader = await CarReader.fromBytes( + await fs.promises.readFile(carPath) + ) + const root = (await reader.getRoots())[0]?.toString() + assert.ok(root) + + const canStore = await storacha + .args(['can', 'blob', 'add', carPath]) + .env(context.env.alice) + .join() + + assert.match(canStore.error, /Stored zQm/) + + const digest = canStore.error.trim().split('\n')[2].split(' ')[2] + const shard = Link.create(0x0202, Digest.decode(base58btc.decode(digest))) + const canUpload = await storacha + .args(['can', 'upload', 'add', root, shard.toString()]) + .env(context.env.alice) + .join() + + assert.match(canUpload.error, /Upload added/) + }), + + 'storacha can upload ls': test(async (assert, context) => { + await loginAndCreateSpace(context) + + await storacha + .args(['up', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + const list = await storacha + .args(['can', 'upload', 'ls', '--json']) + .env(context.env.alice) + .join() + + assert.ok(dagJSON.parse(list.output)) + }), + 'storacha can upload rm': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg']) + .env(context.env.alice) + .join() + + assert.match( + up.output, + /bafybeiajdopsmspomlrpaohtzo5sdnpknbolqjpde6huzrsejqmvijrcea/ + ) + + const noPath = await storacha + .args(['can', 'upload', 'rm']) + .env(context.env.alice) + .join() + .catch() + + assert.match(noPath.error, /Insufficient arguments/) + + const invalidCID = await storacha + .args(['can', 'upload', 'rm', 'foo']) + .env(context.env.alice) + .join() + .catch() + + assert.match(invalidCID.error, /not a CID/) + + const rm = await storacha + .args([ + 'can', + 'upload', + 'rm', + 'bafybeiajdopsmspomlrpaohtzo5sdnpknbolqjpde6huzrsejqmvijrcea', + ]) + .env(context.env.alice) + .join() + + assert.ok(rm.status.success()) + }), + 'can filecoin info with not found': test(async (assert, context) => { + await loginAndCreateSpace(context) + + const up = await storacha + .args(['up', 'test/fixtures/pinpie.jpg', '--verbose']) + .env(context.env.alice) + .join() + const pieceCid = up.error.split('Piece CID: ')[1].split(`\n`)[0] + + const { error } = await storacha + .args(['can', 'filecoin', 'info', pieceCid, '--json']) + .env(context.env.alice) + .join() + .catch() + // no piece will be available right away + assert.ok(error) + assert.ok(error.includes('not found')) + }), +} + +export const testPlan = { + 'storacha plan get': test(async (assert, context) => { + await login(context) + const notFound = await storacha + .args(['plan', 'get']) + .env(context.env.alice) + .join() + + assert.match(notFound.output, /no plan/i) + + await selectPlan(context) + + // wait a second for invocation to get a different expiry + await new Promise((resolve) => setTimeout(resolve, 1000)) + + const plan = await storacha + .args(['plan', 'get']) + .env(context.env.alice) + .join() + assert.match(plan.output, /did:web:free.web3.storage/) + }), +} + +export const testKey = { + 'storacha key create': test(async (assert) => { + const res = await storacha.args(['key', 'create', '--json']).join() + const key = ED25519.parse(JSON.parse(res.output).key) + assert.ok(key.did().startsWith('did:key')) + }), +} + +export const testBridge = { + 'storacha bridge generate-tokens': test(async (assert, context) => { + const spaceDID = await loginAndCreateSpace(context) + const res = await storacha + .args(['bridge', 'generate-tokens', spaceDID]) + .join() + assert.match(res.output, /X-Auth-Secret header: u/) + assert.match(res.output, /Authorization header: u/) + }), +} + +/** + * @param {Test.Context} context + * @param {object} options + * @param {string} [options.email] + * @param {Record} [options.env] + */ +export const login = async ( + context, + { email = 'alice@web.mail', env = context.env.alice } = {} +) => { + const login = storacha.env(env).args(['login', email]).fork() + + // wait for the new process to print the status + await login.error.lines().take().text() + + // receive authorization request + const message = await context.mail.take() + + // confirm authorization + await context.grantAccess(message) + + return await login.join() +} + +/** + * @typedef {import('@storacha/client/types').ProviderDID} Plan + * + * @param {Test.Context} context + * @param {object} options + * @param {DIDMailto.EmailAddress} [options.email] + * @param {string} [options.billingID] + * @param {Plan} [options.plan] + */ +export const selectPlan = async ( + context, + { + email = 'alice@web.mail', + billingID = 'test:cus_alice', + plan = 'did:web:free.web3.storage', + } = {} +) => { + const customer = DIDMailto.fromEmail(email) + Result.try(await context.plansStorage.initialize(customer, billingID, plan)) +} + +/** + * @param {Test.Context} context + * @param {object} options + * @param {DIDMailto.EmailAddress|null} [options.customer] + * @param {string} [options.name] + * @param {Record} [options.env] + */ +export const createSpace = async ( + context, + { customer = 'alice@web.mail', name = 'home', env = context.env.alice } = {} +) => { + const { output } = await storacha + .args([ + 'space', + 'create', + name, + '--no-recovery', + '--no-account', + '--no-gateway-authorization', + ...(customer ? ['--customer', customer] : ['--no-customer']), + ]) + .env(env) + .join() + + const [did] = match(/(did:key:\w+)/, output) + + return SpaceDID.from(did) +} + +/** + * @param {Test.Context} context + * @param {object} options + * @param {DIDMailto.EmailAddress} [options.email] + * @param {DIDMailto.EmailAddress|null} [options.customer] + * @param {string} [options.name] + * @param {Plan} [options.plan] + * @param {Record} [options.env] + */ +export const loginAndCreateSpace = async ( + context, + { + email = 'alice@web.mail', + customer = email, + name = 'home', + plan = 'did:web:free.web3.storage', + env = context.env.alice, + } = {} +) => { + await login(context, { email, env }) + + if (customer != null && plan != null) { + await selectPlan(context, { email: customer, plan }) + } + + return createSpace(context, { customer, name, env }) +} + +/** + * @param {Test.Context} context + * @param {object} options + * @param {string} [options.password] + */ +export const createCustomerSession = async ( + context, + { password = '' } = {} +) => { + // Derive delegation audience from the password + const { digest } = await sha256.digest(new TextEncoder().encode(password)) + const audience = await ED25519.derive(digest) + + // Generate the agent that will be authorized to act on behalf of the customer + const agent = await ed25519.generate() + + const customer = Absentee.from({ id: 'did:mailto:web.mail:workshop' }) + + // First we create delegation from the customer to the agent that authorizing + // it to perform `provider/add` on their behalf. + const delegation = await delegate({ + issuer: customer, + audience: agent, + capabilities: [ + { + with: 'ucan:*', + can: '*', + }, + ], + expiration: Infinity, + }) + + // Then we create an attestation from the service to proof that agent has + // been authorized + const attestation = await UCAN.attest.delegate({ + issuer: context.service, + audience: agent, + with: context.service.did(), + nb: { proof: delegation.cid }, + expiration: delegation.expiration, + }) + + // Finally we create a short lived session that authorizes the audience to + // provider/add with their billing account. + const session = await Provider.add.delegate({ + issuer: agent, + audience, + with: customer.did(), + proofs: [delegation, attestation], + }) + + return Result.try(await session.archive()) +} diff --git a/packages/cli/test/fixtures/empty.car b/packages/cli/test/fixtures/empty.car new file mode 100644 index 000000000..3e0962954 --- /dev/null +++ b/packages/cli/test/fixtures/empty.car @@ -0,0 +1 @@ +erootsgversion \ No newline at end of file diff --git a/packages/cli/test/fixtures/pinpie.car b/packages/cli/test/fixtures/pinpie.car new file mode 100644 index 000000000..779fbef4d Binary files /dev/null and b/packages/cli/test/fixtures/pinpie.car differ diff --git a/packages/cli/test/fixtures/pinpie.jpg b/packages/cli/test/fixtures/pinpie.jpg new file mode 100644 index 000000000..1ea4a2c92 Binary files /dev/null and b/packages/cli/test/fixtures/pinpie.jpg differ diff --git a/packages/cli/test/helpers/context.js b/packages/cli/test/helpers/context.js new file mode 100644 index 000000000..98ed86bfb --- /dev/null +++ b/packages/cli/test/helpers/context.js @@ -0,0 +1,128 @@ +import * as API from '../../api.js' + +import { + createContext, + cleanupContext, +} from '@storacha/upload-api/test/context' +import { createEnv } from './env.js' +import { Signer } from '@ucanto/principal/ed25519' +import { createServer as createHTTPServer } from './http-server.js' +import { createReceiptsServer } from './receipt-http-server.js' +import http from 'node:http' +import { StoreConf } from '@storacha/client/stores/conf' +import * as FS from 'node:fs/promises' + +/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */ +export const alice = Signer.parse( + 'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM=' +) +/** did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob */ +export const bob = Signer.parse( + 'MgCYbj5AJfVvdrjkjNCxB3iAUwx7RQHVQ7H1sKyHy46Iose0BEevXgL1V73PD9snOCIoONgb+yQ9sycYchQC8kygR4qY=' +) +/** did:key:z6MktafZTREjJkvV5mfJxcLpNBoVPwDLhTuMg9ng7dY4zMAL */ +export const mallory = Signer.parse( + 'MgCYtH0AvYxiQwBG6+ZXcwlXywq9tI50G2mCAUJbwrrahkO0B0elFYkl3Ulf3Q3A/EvcVY0utb4etiSE8e6pi4H0FEmU=' +) + +export { createContext, cleanupContext } + +/** + * @typedef {Awaited>} UcantoServerTestContext + * + * @param {UcantoServerTestContext} context + * @param {object} input + * @param {API.DIDKey} input.space + * @param {API.DID<'mailto'>} input.account + * @param {API.DID<'web'>} input.provider + */ +export const provisionSpace = async (context, { space, account, provider }) => { + // add a provider for this space + return await context.provisionsStorage.put({ + cause: /** @type {*} */ ({}), + consumer: space, + customer: account, + provider, + }) +} + +/** + * @typedef {UcantoServerTestContext & { + * server: import('./http-server').TestingServer['server'] + * receiptsServer: import('./receipt-http-server.js').TestingServer['server'] + * router: import('./http-server').Router + * env: { alice: Record, bob: Record } + * serverURL: URL + * }} Context + * + * @returns {Promise} + */ +export const setup = async () => { + const context = await createContext({ http }) + const { server, serverURL, router } = await createHTTPServer({ + '/': context.connection.channel.request.bind(context.connection.channel), + }) + const { server: receiptsServer, serverURL: receiptsServerUrl } = + await createReceiptsServer() + + return Object.assign(context, { + server, + serverURL, + receiptsServer, + router, + serverRouter: router, + env: { + alice: createEnv({ + storeName: `storacha-cli-test-alice-${context.service.did()}`, + servicePrincipal: context.service, + serviceURL: serverURL, + receiptsEndpoint: new URL('receipt', receiptsServerUrl), + }), + bob: createEnv({ + storeName: `storacha-cli-test-bob-${context.service.did()}`, + servicePrincipal: context.service, + serviceURL: serverURL, + receiptsEndpoint: new URL('receipt', receiptsServerUrl), + }), + }, + }) +} + +/** + * @param {Context} context + */ +export const teardown = async (context) => { + await cleanupContext(context) + context.server.close() + context.receiptsServer.close() + + const stores = [ + context.env.alice.STORACHA_STORE_NAME, + context.env.bob.STORACHA_STORE_NAME, + ] + + await Promise.all( + stores.map(async (name) => { + const { path } = new StoreConf({ profile: name }) + try { + await FS.rm(path) + } catch (/** @type {any} */ err) { + if (err.code === 'ENOENT') return // is ok maybe it wasn't used in the test + throw err + } + }) + ) +} + +/** + * @param {(assert: import('entail').Assert, context: Context) => unknown} unit + * @returns {import('entail').Test} + */ +export const test = (unit) => async (assert) => { + const context = await setup() + try { + await unit(assert, context) + } finally { + await teardown(context) + } +} diff --git a/packages/cli/test/helpers/env.js b/packages/cli/test/helpers/env.js new file mode 100644 index 000000000..58249539e --- /dev/null +++ b/packages/cli/test/helpers/env.js @@ -0,0 +1,19 @@ +/** + * @param {object} [options] + * @param {import('@ucanto/interface').Principal} [options.servicePrincipal] + * @param {URL} [options.serviceURL] + * @param {string} [options.storeName] + * @param {URL} [options.receiptsEndpoint] + */ +export function createEnv(options = {}) { + const { servicePrincipal, serviceURL, storeName, receiptsEndpoint } = options + const env = { STORACHA_STORE_NAME: storeName ?? 'storacha-test' } + if (servicePrincipal && serviceURL) { + Object.assign(env, { + STORACHA_SERVICE_DID: servicePrincipal.did(), + STORACHA_SERVICE_URL: serviceURL.toString(), + STORACHA_RECEIPTS_URL: receiptsEndpoint?.toString(), + }) + } + return env +} diff --git a/packages/cli/test/helpers/http-server.js b/packages/cli/test/helpers/http-server.js new file mode 100644 index 000000000..375d2e834 --- /dev/null +++ b/packages/cli/test/helpers/http-server.js @@ -0,0 +1,61 @@ +import http from 'node:http' +import { once } from 'node:events' + +/** + * @typedef {import('@ucanto/interface').HTTPRequest} HTTPRequest + * @typedef {import('@ucanto/server').HTTPResponse} HTTPResponse + * @typedef {Record PromiseLike|HTTPResponse>} Router + * + * @typedef {{ + * server: http.Server + * serverURL: URL + * router: Router + * }} TestingServer + */ + +/** + * @param {Router} router + * @returns {Promise} + */ +export async function createServer(router) { + /** + * @param {http.IncomingMessage} request + * @param {http.ServerResponse} response + */ + const listener = async (request, response) => { + const chunks = [] + for await (const chunk of request) { + chunks.push(chunk) + } + + const handler = router[request.url ?? '/'] + if (!handler) { + response.writeHead(404) + response.end() + return undefined + } + + const { headers, body } = await handler({ + headers: /** @type {Readonly>} */ ( + request.headers + ), + body: Buffer.concat(chunks), + }) + + response.writeHead(200, headers) + response.write(body) + response.end() + return undefined + } + + const server = http.createServer(listener).listen() + + await once(server, 'listening') + + return { + server, + router, + // @ts-expect-error + serverURL: new URL(`http://127.0.0.1:${server.address().port}`), + } +} diff --git a/packages/cli/test/helpers/process.js b/packages/cli/test/helpers/process.js new file mode 100644 index 000000000..70eb682e1 --- /dev/null +++ b/packages/cli/test/helpers/process.js @@ -0,0 +1,177 @@ +import Process from 'node:child_process' +import { TextDecoder } from 'node:util' +import { ByteStream } from './stream.js' + +/** + * @typedef {object} Command + * @property {string} program + * @property {string[]} args + * @property {Record} env + * + * @typedef {object} Outcome + * @property {Status} status + * @property {string} output + * @property {string} error + * + * + * @param {string} program + */ +export const create = (program) => + new CommandView({ + program, + args: [], + env: process.env, + }) + +class CommandView { + /** + * @param {Command} model + */ + constructor(model) { + this.model = model + } + + /** + * @param {string[]} args + */ + args(args) { + return new CommandView({ + ...this.model, + args: [...this.model.args, ...args], + }) + } + + /** + * @param {Record} env + */ + env(env) { + return new CommandView({ + ...this.model, + env: { ...this.model.env, ...env }, + }) + } + + fork() { + return fork(this.model) + } + + join() { + return join(this.model) + } +} + +/** + * @param {Command} command + */ +export const fork = (command) => { + const process = Process.spawn(command.program, command.args, { + env: command.env, + }) + return new Fork(process) +} + +/** + * @param {Command} command + */ +export const join = (command) => fork(command).join() + +class Status { + /** + * @param {{code:number, signal?: void}|{signal:NodeJS.Signals, code?:void}} model + */ + constructor(model) { + this.model = model + } + + success() { + return this.model.code === 0 + } + + get code() { + return this.model.code ?? null + } + get signal() { + return this.model.signal ?? null + } +} + +class Fork { + /** + * @param {Process.ChildProcess} process + */ + constructor(process) { + this.process = process + this.output = ByteStream.from(process.stdout ?? []) + + this.error = ByteStream.from(process.stderr ?? []) + } + join() { + return new Join(this) + } + terminate() { + this.process.kill() + return this + } +} + +class Join { + /** + * @param {Fork} fork + */ + constructor(fork) { + this.fork = fork + this.output = '' + this.error = '' + + void readInto(fork.output.reader(), this, 'output') + void readInto(fork.error.reader(), this, 'error') + } + + /** + * @param {(ok: Outcome) => unknown} succeed + * @param {(error: Outcome) => unknown} fail + */ + then(succeed, fail) { + this.fork.process.once('close', (code, signal) => { + const status = + signal !== null + ? new Status({ signal }) + : new Status({ code: /** @type {number} */ (code) }) + + const { output, error } = this + const outcome = { status, output, error } + if (status.success()) { + succeed(outcome) + } else { + fail( + Object.assign( + new Error(`command failed with status ${status.code}\n ${error}`), + outcome + ) + ) + } + }) + } + + /** + * @returns {Promise} + */ + catch() { + return Promise.resolve(this).catch((error) => error) + } +} + +/** + * @template {string} Channel + * @param {AsyncIterable} source + * @param {{[key in Channel]: string}} output + * @param {Channel} channel + */ +const readInto = async (source, output, channel) => { + const decoder = new TextDecoder() + for await (const chunk of source) { + // Uncomment to debugger easily + // console.log(decoder.decode(chunk)) + output[channel] += decoder.decode(chunk) + } +} diff --git a/packages/cli/test/helpers/random.js b/packages/cli/test/helpers/random.js new file mode 100644 index 000000000..1f4447696 --- /dev/null +++ b/packages/cli/test/helpers/random.js @@ -0,0 +1,61 @@ +import { CarWriter } from '@ipld/car' +import * as CAR from '@ucanto/transport/car' +import { CID } from 'multiformats/cid' +import * as raw from 'multiformats/codecs/raw' +import { sha256 } from 'multiformats/hashes/sha2' + +/** @param {number} size */ +export async function randomBytes(size) { + const bytes = new Uint8Array(size) + while (size) { + const chunk = new Uint8Array(Math.min(size, 65_536)) + if (!globalThis.crypto) { + try { + const { webcrypto } = await import('node:crypto') + webcrypto.getRandomValues(chunk) + } catch (err) { + throw new Error( + 'unknown environment - no global crypto and not Node.js', + { cause: err } + ) + } + } else { + crypto.getRandomValues(chunk) + } + size -= chunk.length + bytes.set(chunk, size) + } + return bytes +} + +/** @param {number} size */ +export async function randomCAR(size) { + const bytes = await randomBytes(size) + return toCAR(bytes) +} + +/** @param {Uint8Array} bytes */ +export async function toBlock(bytes) { + const hash = await sha256.digest(bytes) + const cid = CID.createV1(raw.code, hash) + return { cid, bytes } +} + +/** + * @param {Uint8Array} bytes + */ +export async function toCAR(bytes) { + const block = await toBlock(bytes) + const { writer, out } = CarWriter.create(block.cid) + void writer.put(block) + void writer.close() + + const chunks = [] + for await (const chunk of out) { + chunks.push(chunk) + } + const blob = new Blob(chunks) + const cid = await CAR.codec.link(new Uint8Array(await blob.arrayBuffer())) + + return Object.assign(blob, { cid, roots: [block.cid] }) +} diff --git a/packages/cli/test/helpers/receipt-http-server.js b/packages/cli/test/helpers/receipt-http-server.js new file mode 100644 index 000000000..e04f0efec --- /dev/null +++ b/packages/cli/test/helpers/receipt-http-server.js @@ -0,0 +1,80 @@ +import http from 'node:http' +import { once } from 'node:events' + +import { parseLink } from '@ucanto/server' +import * as Signer from '@ucanto/principal/ed25519' +import { Receipt, Message } from '@ucanto/core' +import * as CAR from '@ucanto/transport/car' +import { Assert } from '@web3-storage/content-claims/capability' +import { randomCAR } from './random.js' + +/** + * @typedef {{ + * server: http.Server + * serverURL: URL + * }} TestingServer + */ + +/** + * @returns {Promise} + */ +export async function createReceiptsServer() { + /** + * @param {http.IncomingMessage} request + * @param {http.ServerResponse} response + */ + const listener = async (request, response) => { + const taskCid = request.url?.split('/')[1] ?? '' + const body = await generateReceipt(taskCid) + response.writeHead(200) + response.end(body) + return undefined + } + + const server = http.createServer(listener).listen() + + await once(server, 'listening') + + return { + server, + // @ts-expect-error + serverURL: new URL(`http://127.0.0.1:${server.address().port}`), + } +} + +/** + * @param {string} taskCid + */ +const generateReceipt = async (taskCid) => { + const issuer = await Signer.generate() + const content = (await randomCAR(128)).cid + const locationClaim = await Assert.location.delegate({ + issuer, + audience: issuer, + with: issuer.toDIDKey(), + nb: { + content, + location: ['http://localhost'], + }, + expiration: Infinity, + }) + + const receipt = await Receipt.issue({ + issuer, + fx: { + fork: [locationClaim], + }, + /** @ts-expect-error not a UCAN Link */ + ran: parseLink(taskCid), + result: { + ok: { + site: locationClaim.link(), + }, + }, + }) + + const message = await Message.build({ + receipts: [receipt], + }) + return CAR.request.encode(message).body +} diff --git a/packages/cli/test/helpers/stream.js b/packages/cli/test/helpers/stream.js new file mode 100644 index 000000000..1447886bc --- /dev/null +++ b/packages/cli/test/helpers/stream.js @@ -0,0 +1,489 @@ +const empty = () => EMPTY + +/** + * @template {{}} T + * @typedef {ReadableStream|AsyncIterable|Iterable} Source + */ + +/** + * @template {{}} T + * @param {Source} source + * @returns {Resource} + */ +const toResource = (source) => { + if ('getReader' in source) { + return source.getReader() + } else { + const iterator = + Symbol.asyncIterator in source + ? source[Symbol.asyncIterator]() + : source[Symbol.iterator]() + + return { + async read() { + return /** @type {ReadableStreamReadResult} */ ( + await iterator.next() + ) + }, + releaseLock() { + return iterator.return?.() + }, + async cancel(reason) { + if (reason != null) { + if (iterator.throw) { + await iterator.throw(reason) + } else if (iterator.return) { + await iterator.return() + } + } else { + await iterator.return?.() + } + }, + } + } +} + +/** + * @template {{}} T + * @param {ReadableStream|AsyncIterable|Iterable} source + * @returns {Stream} + */ +export const from = (source) => new Stream(toResource(source), {}, Direct) + +/** + * @template {{}} T + * @param {Resource} source + * @param {number} n + * @returns {Stream} + */ +const take = (source, n = 1) => + new Stream(source, n, /** @type {Transform} */ (Take)) + +const Take = { + /** + * @template T + * @param {number} n + * @param {T} input + * @returns {[number|undefined, T[]]} + */ + write: (n, input) => { + if (n > 0) { + return input != null ? [n - 1, [input]] : [n, []] + } else { + return [undefined, []] + } + }, + flush: empty, +} + +/** + * @param {Resource} source + * @returns {ByteStream<{}>} + */ +const toByteStream = (source) => new ByteStream(source, {}, Direct) + +/** + * @template {{}} T + * @param {Resource} source + * @returns {Reader} + */ +const toReader = (source) => new Reader(source) + +/** + * @template T + * @param {Resource} source + */ +const collect = async (source) => { + const chunks = [] + for await (const chunk of iterate(source)) { + chunks.push(chunk) + } + + return chunks +} + +/** + * @param {Resource} source + * @param {number} chunkSize + * @returns {ByteStream} + */ +const chop = (source, chunkSize) => + new ByteStream(source, new Uint8Array(chunkSize), Chop) + +const Chop = { + /** + * @param {Uint8Array} bytes + * @param {Uint8Array} input + * @returns {[Uint8Array, Uint8Array[]]} + */ + write(bytes, input) { + const { byteLength } = bytes.buffer + if (bytes.length + input.length < byteLength) { + const buffer = new Uint8Array( + bytes.buffer, + 0, + bytes.length + input.length + ) + buffer.set(input, bytes.length) + return [buffer, []] + } else { + const chunk = new Uint8Array(byteLength) + chunk.set(bytes, 0) + chunk.set(input.slice(0, byteLength - bytes.length), bytes.length) + + const chunks = [chunk] + + let offset = byteLength - bytes.length + while (offset + byteLength < input.length) { + chunks.push(input.subarray(offset, offset + byteLength)) + offset += byteLength + } + + const buffer = new Uint8Array(bytes.buffer, 0, input.length - offset) + buffer.set(input.subarray(offset), 0) + + return [buffer, chunks] + } + }, + /** + * @param {Uint8Array} bytes + */ + flush(bytes) { + return bytes.length ? [bytes] : [] + }, +} + +/** + * @param {Resource} source + * @param {number} byte + */ +const delimit = (source, byte) => + new ByteStream(source, { buffer: new Uint8Array(0), code: byte }, Delimiter) + +const Delimiter = { + /** + * @param {{code: number, buffer:Uint8Array}} state + * @param {Uint8Array} input + * @returns {[{code: number, buffer:Uint8Array}|undefined, Uint8Array[]]} + */ + write({ code, buffer }, input) { + let start = 0 + let end = 0 + const chunks = [] + while (end < input.length) { + const byte = input[end] + end++ + if (byte === code) { + const segment = input.subarray(start, end) + if (buffer.length > 0) { + const chunk = new Uint8Array(buffer.length + segment.length) + chunk.set(buffer, 0) + chunk.set(segment, buffer.length) + chunks.push(chunk) + buffer = new Uint8Array(0) + } else { + chunks.push(segment) + } + start = end + } + } + + const segment = input.subarray(start, end) + const chunk = new Uint8Array(buffer.length + segment.length) + chunk.set(buffer, 0) + chunk.set(segment, buffer.length) + + return [{ code, buffer }, chunks] + }, + /** + * @param {{code: number, buffer:Uint8Array}} state + */ + flush({ buffer }) { + return buffer.length ? [buffer] : [] + }, +} + +/** + * @template {{}} Out + * @template {{}} State + * @template {{}} [In=Out] + * @typedef {object} Transform + * @property {(state: State, input: In) => [State|undefined, Out[]]} write + * @property {(state: State) => Out[]} flush + */ +/** + * @template {{}} Out + * @template {{}} State + * @template {{}} In + * @param {Resource} source + * @param {State} state + * @param {Transform} transform + * @returns {Stream} + */ +const transform = (source, state, transform) => + new Stream(source, state, transform) + +/** + * @template T + * @param {Resource} source + */ +const iterate = async function* (source) { + try { + while (true) { + const { value, done } = await source.read() + if (done) break + yield value + } + } catch (error) { + source.cancel(/** @type {{}} */ (error)) + source.releaseLock() + throw error + } +} + +const Direct = { + /** + * @template {{}} T + * @template {{}} State + * @param {State} state + * @param {T} input + */ + write(state, input) { + OUT.pop() + if (input != null) { + OUT.push(input) + } + STEP[0] = state + return STEP + }, + /** + * @returns {never[]} + */ + flush() { + return EMPTY + }, +} +/** + * @template {{}} Out + * @template {{}} [State={}] + * @template {{}} [In=Out] + * @extends {ReadableStream} + */ +export class Stream extends ReadableStream { + /** + * @param {Resource} source + * @param {State} state + * @param {Transform} transformer + */ + constructor(source, state, { write, flush }) { + super({ + /** + * @param {ReadableStreamDefaultController} controller + */ + pull: async (controller) => { + try { + const { done, value } = await source.read() + if (done) { + controller.close() + source.releaseLock() + } else { + const [next, output] = write(state, value) + for (const item of output) { + controller.enqueue(item) + } + + if (next) { + state = next + } else { + controller.close() + source.cancel() + source.releaseLock() + } + } + } catch (error) { + controller.error(error) + source.releaseLock() + } + }, + cancel(controller) { + source.cancel() + source.releaseLock() + for (const item of flush(state)) { + controller.enqueue(item) + } + }, + }) + } + + /** + * @template {{}} State + * @template {{}} T + * @param {State} state + * @param {Transform} transformer + */ + transform(state, transformer) { + return transform(this.getReader(), state, transformer) + } + + /** + * @returns {Reader} + */ + reader() { + return toReader(this.getReader()) + } + + /** + * @returns {AsyncIterable} + */ + [Symbol.asyncIterator]() { + return iterate(this.getReader()) + } + + /** + * @param {number} n + */ + take(n = 1) { + return take(this.getReader(), n) + } + + collect() { + return collect(this.getReader()) + } +} + +/** + * @template {{}} [State={}] + * @extends {Stream} + */ +export class ByteStream extends Stream { + /** + * @param {Source} source + */ + static from(source) { + return new ByteStream(toResource(source), {}, Direct) + } + + reader() { + return new BytesReader(this.getReader()) + } + + text() { + return this.reader().text() + } + bytes() { + return this.reader().bytes() + } + + /** + * @param {number} n + */ + take(n = 1) { + return toByteStream(take(this.getReader(), n).getReader()) + } + /** + * @param {number} size + */ + chop(size) { + return chop(this.getReader(), size) + } + + /** + * @param {number} byte + */ + delimit(byte) { + return delimit(this.getReader(), byte) + } + + lines() { + return this.delimit('\n'.charCodeAt(0)) + } +} + +/** + * @template T + * @typedef {object} Resource + * @property {() => Promise>} read + * @property {() => void} releaseLock + * @property {(reason?: {}) => void} cancel + */ + +/** @type {never[]} */ +const EMPTY = [] + +/** @type {any[]} */ +const OUT = [] +/** @type {[any, any[]]} */ +const STEP = [{}, OUT] + +/** + * @template {{}} T + */ +class Reader { + /** + * @param {Resource} source + */ + constructor(source) { + this.source = source + } + read() { + return this.source.read() + } + releaseLock() { + return this.source.releaseLock() + } + + /** + * @param {{}} [reason] + */ + cancel(reason) { + const result = this.source.cancel(reason) + this.source.releaseLock() + return result + } + async *[Symbol.asyncIterator]() { + while (true) { + const { value, done } = await this.read() + if (done) break + yield value + } + this.cancel() + } + + take(n = 1) { + return take(this.source, n).reader() + } + + collect() { + return collect(this.source) + } +} + +/** + * @extends {Reader} + */ +class BytesReader extends Reader { + async bytes() { + const chunks = [] + let length = 0 + for await (const chunk of this) { + chunks.push(chunk) + length += chunk.length + } + + const bytes = new Uint8Array(length) + let offset = 0 + for (const chunk of chunks) { + bytes.set(chunk, offset) + offset += chunk.length + } + + return bytes + } + async text() { + return new TextDecoder().decode(await this.bytes()) + } + + take(n = 1) { + return ByteStream.from(take(this.source, n)).reader() + } +} diff --git a/packages/cli/test/helpers/util.js b/packages/cli/test/helpers/util.js new file mode 100644 index 000000000..b39811e50 --- /dev/null +++ b/packages/cli/test/helpers/util.js @@ -0,0 +1,19 @@ +/** + * @param {{ raw: ArrayLike }} template + * @param {unknown[]} substitutions + */ +export const pattern = (template, ...substitutions) => + new RegExp(String.raw(template, ...substitutions)) + +/** + * @param {RegExp} pattern + * @param {string} source + * @returns {string[]} + */ +export const match = (pattern, source) => { + const match = source.match(pattern) + if (!match) { + return [] + } + return match +} diff --git a/packages/cli/test/lib.spec.js b/packages/cli/test/lib.spec.js new file mode 100644 index 000000000..6ed711154 --- /dev/null +++ b/packages/cli/test/lib.spec.js @@ -0,0 +1,101 @@ +import * as Link from 'multiformats/link' +import { filesize, uploadListResponseToString } from '../lib.js' + +/** + * @typedef {import('multiformats').LinkJSON} LinkJSON + * @typedef {import('@storacha/client/types').CARLink} CARLink + */ + +/** @type {import('entail').Suite} */ +export const testFilesize = { + filesize: (assert) => { + /** @type {Array<[number, string]>} */ + const testdata = [ + [5, '5B'], + [50, '0.1KB'], + [500, '0.5KB'], + [5_000, '5.0KB'], + [50_000, '0.1MB'], + [500_000, '0.5MB'], + [5_000_000, '5.0MB'], + [50_000_000, '0.1GB'], + [500_000_000, '0.5GB'], + [5_000_000_000, '5.0GB'], + ] + testdata.forEach(([size, str]) => assert.equal(filesize(size), str)) + }, +} + +/** @type {import('@storacha/client/types').UploadListSuccess} */ +const uploadListResponse = { + size: 2, + cursor: 'bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje', + results: [ + { + root: Link.parse( + 'bafybeia7tr4dgyln7zeyyyzmkppkcts6azdssykuluwzmmswysieyadcbm' + ), + shards: [ + Link.parse( + 'bagbaierantza4rfjnhqksp2stcnd2tdjrn3f2kgi2wrvaxmayeuolryi66fq' + ), + ], + updatedAt: new Date().toISOString(), + insertedAt: new Date().toISOString(), + }, + { + root: Link.parse( + 'bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje' + ), + shards: [ + Link.parse( + 'bagbaieraxqbkzwvx5on6an4br5hagfgesdfc6adchy3hf5qt34pupfjd3rbq' + ), + ], + updatedAt: new Date().toISOString(), + insertedAt: new Date().toISOString(), + }, + ], + after: 'bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje', + before: 'bafybeia7tr4dgyln7zeyyyzmkppkcts6azdssykuluwzmmswysieyadcbm', +} + +/** @type {import('entail').Suite} */ +export const testUpload = { + 'uploadListResponseToString can return the upload roots CIDs as strings': ( + assert + ) => { + assert.equal( + uploadListResponseToString(uploadListResponse, {}), + `bafybeia7tr4dgyln7zeyyyzmkppkcts6azdssykuluwzmmswysieyadcbm +bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje` + ) + }, + + 'uploadListResponseToString can return the upload roots as newline delimited JSON': + (assert) => { + assert.equal( + uploadListResponseToString(uploadListResponse, { + shards: true, + plainTree: true, + }), + `bafybeia7tr4dgyln7zeyyyzmkppkcts6azdssykuluwzmmswysieyadcbm +└─┬ shards + └── bagbaierantza4rfjnhqksp2stcnd2tdjrn3f2kgi2wrvaxmayeuolryi66fq + +bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje +└─┬ shards + └── bagbaieraxqbkzwvx5on6an4br5hagfgesdfc6adchy3hf5qt34pupfjd3rbq +` + ) + }, + + 'uploadListResponseToString can return the upload roots and shards as a tree': + (assert) => { + assert.equal( + uploadListResponseToString(uploadListResponse, { json: true }), + `{"root":{"/":"bafybeia7tr4dgyln7zeyyyzmkppkcts6azdssykuluwzmmswysieyadcbm"},"shards":[{"/":"bagbaierantza4rfjnhqksp2stcnd2tdjrn3f2kgi2wrvaxmayeuolryi66fq"}]} +{"root":{"/":"bafybeibvbxjeodaa6hdqlgbwmv4qzdp3bxnwdoukay4dpl7aemkiwc2eje"},"shards":[{"/":"bagbaieraxqbkzwvx5on6an4br5hagfgesdfc6adchy3hf5qt34pupfjd3rbq"}]}` + ) + }, +} diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json new file mode 100644 index 000000000..7c59f301c --- /dev/null +++ b/packages/cli/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "strict": true, + "outDir": "dist", + // project options + "allowJs": true, + "checkJs": true, + "target": "ES2022", + "module": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "noEmit": true, + "isolatedModules": true, + "removeComments": false, + // module resolution + "esModuleInterop": true, + "moduleResolution": "Node", + // linter checks + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": true, + "noUnusedParameters": false, + // advanced + "importsNotUsedAsValues": "remove", + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "stripInternal": true, + "resolveJsonModule": true + } +} diff --git a/packages/did-mailto/CHANGELOG.md b/packages/did-mailto/CHANGELOG.md index 19f0096d1..8364cca01 100644 --- a/packages/did-mailto/CHANGELOG.md +++ b/packages/did-mailto/CHANGELOG.md @@ -1,5 +1,56 @@ # Changelog +## [1.0.1](https://github.com/storacha/upload-service/compare/did-mailto-v1.0.0...did-mailto-v1.0.1) (2024-12-19) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## 1.0.0 (2024-11-05) + + +### Fixes + +* bootstrap sha ([cdf6737](https://github.com/storacha/upload-service/commit/cdf67371ee9df3a60f7fea90c310179b20ee2b0b)) + + +### Other Changes + +* **main:** release did-mailto 1.0.0 ([#7](https://github.com/storacha/upload-service/issues/7)) ([2f7ab28](https://github.com/storacha/upload-service/commit/2f7ab286a7fd22249ed3ee2bd05b6a5d22e69cf0)) + +## 1.0.0 (2024-11-05) + + +### Features + +* add usage/report capability ([#1079](https://github.com/storacha/upload-service/issues/1079)) ([6418b4b](https://github.com/storacha/upload-service/commit/6418b4b22329a118fb258928bd9a6a45ced5ce45)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) + + +### Fixes + +* fix arethetypesworking errors in all packages ([#1004](https://github.com/storacha/upload-service/issues/1004)) ([2e2936a](https://github.com/storacha/upload-service/commit/2e2936a3831389dd13be5be5146a04e2b15553c5)) +* floating promises and add no-floating-promises to eslint-config-w3up ([#1198](https://github.com/storacha/upload-service/issues/1198)) ([1b8c5aa](https://github.com/storacha/upload-service/commit/1b8c5aa86ec3d177bf77df4e2916699c1f522598)) +* issue where typedoc docs would only show full docs for w3up-client ([#1141](https://github.com/storacha/upload-service/issues/1141)) ([0b8d3f3](https://github.com/storacha/upload-service/commit/0b8d3f3b52918b1b4d3b76ea6fea3fb0c837cd73)) +* migrate repo ([#1389](https://github.com/storacha/upload-service/issues/1389)) ([475a287](https://github.com/storacha/upload-service/commit/475a28743ff9f7138b46dfe4227d3c80ed75a6a2)) +* package metadata ([#1161](https://github.com/storacha/upload-service/issues/1161)) ([b8a1cc2](https://github.com/storacha/upload-service/commit/b8a1cc2e125a91be582998bda295e1ae1caab087)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* correct typo in index.js error ([#1204](https://github.com/storacha/upload-service/issues/1204)) ([f54b343](https://github.com/storacha/upload-service/commit/f54b34317195ff51f87bd68db1cc8c36748eac50)) +* **main:** release did-mailto 2.0.2 ([#964](https://github.com/storacha/upload-service/issues/964)) ([83a8263](https://github.com/storacha/upload-service/commit/83a826339ece3eb263bcf2394a21a8aeb8e397d2)) +* **main:** release did-mailto 2.1.0 ([#1080](https://github.com/storacha/upload-service/issues/1080)) ([50543f1](https://github.com/storacha/upload-service/commit/50543f10d8e0186b85ace94f228ba82977c76e77)) +* no longer depends on hd-scripts, packages use/configure eslint directly, fixes warnings from npm lint script ([#1058](https://github.com/storacha/upload-service/issues/1058)) ([ebdb99b](https://github.com/storacha/upload-service/commit/ebdb99b0d3fc912f93ace3d533b915f844b35856)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [2.1.0](https://github.com/web3-storage/w3up/compare/did-mailto-v2.0.2...did-mailto-v2.1.0) (2023-11-09) diff --git a/packages/did-mailto/package.json b/packages/did-mailto/package.json index bd2c29c6c..7377f3be5 100644 --- a/packages/did-mailto/package.json +++ b/packages/did-mailto/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/did-mailto", - "version": "2.1.0", + "name": "@storacha/did-mailto", + "version": "1.0.1", "description": "did:mailto", - "homepage": "https://web3.storage", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/did-mailto" }, "license": "(Apache-2.0 OR MIT)", @@ -38,15 +38,15 @@ "test-watch": "pnpm build && mocha --bail --timeout 10s --watch --parallel -n no-warnings -n experimental-vm-modules -n experimental-fetch --watch-files src,test" }, "devDependencies": { + "@storacha/eslint-config": "workspace:^", "@types/assert": "^1.5.6", "@types/mocha": "^10.0.1", - "@web3-storage/eslint-config-w3up": "workspace:^", "mocha": "^10.2.0", "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" diff --git a/packages/eslint-config-w3up/package.json b/packages/eslint-config-w3up/package.json index 2ded178e4..a35a74086 100644 --- a/packages/eslint-config-w3up/package.json +++ b/packages/eslint-config-w3up/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/eslint-config-w3up", - "version": "1.0.0", - "description": "eslint rules for w3up", - "homepage": "https://web3.storage", + "name": "@storacha/eslint-config", + "version": "0.0.0", + "description": "eslint rules", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/eslint-config-w3up" }, "main": "index.js", diff --git a/packages/filecoin-api/CHANGELOG.md b/packages/filecoin-api/CHANGELOG.md index 65a7ddb52..2dfa68bb5 100644 --- a/packages/filecoin-api/CHANGELOG.md +++ b/packages/filecoin-api/CHANGELOG.md @@ -1,5 +1,114 @@ # Changelog +## [1.1.1](https://github.com/storacha/upload-service/compare/filecoin-api-v1.1.0...filecoin-api-v1.1.1) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.1.0](https://github.com/storacha/upload-service/compare/filecoin-api-v1.0.0...filecoin-api-v1.1.0) (2024-12-19) + + +### Features + +* content serve authorization ([#1590](https://github.com/storacha/upload-service/issues/1590)) + set default gateway ([#99](https://github.com/storacha/upload-service/issues/99)) ([6cbb202](https://github.com/storacha/upload-service/commit/6cbb2027c829189937363b374e258bb1a2b07722)) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## 1.0.0 (2024-12-02) + + +### ⚠ BREAKING CHANGES + +* **upload-api:** integrate agent store for idempotence & invocation/receipt persistence ([#1444](https://github.com/storacha/upload-service/issues/1444)) +* dataStore in storefront renamed to contentStore +* not possible to skip submit queue on storefront service anymore +* return allocated bytes in `store/add` receipt ([#1213](https://github.com/storacha/upload-service/issues/1213)) + +### Features + +* add blob protocol to upload-client ([#1425](https://github.com/storacha/upload-service/issues/1425)) ([49aef56](https://github.com/storacha/upload-service/commit/49aef564a726d34dbbedbd83f5366d9320180f99)) +* add support to prepend pieces while buffering to aggregate ([#1301](https://github.com/storacha/upload-service/issues/1301)) ([dff1846](https://github.com/storacha/upload-service/commit/dff1846ad8b6ff5bb9e5fd8ff71f79df5bf79e4d)) +* add usage/report capability ([#1079](https://github.com/storacha/upload-service/issues/1079)) ([6418b4b](https://github.com/storacha/upload-service/commit/6418b4b22329a118fb258928bd9a6a45ced5ce45)) +* aggregator keeping oldest piece ts ([#1188](https://github.com/storacha/upload-service/issues/1188)) ([97a7def](https://github.com/storacha/upload-service/commit/97a7defa433b57591f23eddee692445437a718a1)) +* api waits for trigger filecoin pipeline from the client ([#1332](https://github.com/storacha/upload-service/issues/1332)) ([421bacb](https://github.com/storacha/upload-service/commit/421bacb9bac8c251cb41f887144e953feaa5558f)) +* filecoin info ([#1091](https://github.com/storacha/upload-service/issues/1091)) ([adb2442](https://github.com/storacha/upload-service/commit/adb24424d1faf50daf2339b77c22fdd44faa236a)) +* **filecoin-api:** allow custom hashing function to be passed to aggregate builder ([#1553](https://github.com/storacha/upload-service/issues/1553)) ([e2653d4](https://github.com/storacha/upload-service/commit/e2653d40c45070e2ccdc5cbda4eb4a35dab302e5)) +* **filecoin-api:** paginated queries ([#1521](https://github.com/storacha/upload-service/issues/1521)) ([25ed7d7](https://github.com/storacha/upload-service/commit/25ed7d7e5208d85c49c18585adb5d8667b81f085)) +* move aggregate information out of deals in filecoin/info ([#1192](https://github.com/storacha/upload-service/issues/1192)) ([18dc590](https://github.com/storacha/upload-service/commit/18dc590ad50a023ef3094bfc1a2d729459e5d68e)) +* return allocated bytes in `store/add` receipt ([#1213](https://github.com/storacha/upload-service/issues/1213)) ([5d52e44](https://github.com/storacha/upload-service/commit/5d52e447c14e7f7fd334e7ff575e032b7b0d89d7)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) +* upgrade ucanto/transport to 9.1.0 in all packages to get more verbose errors from HTTP transport on non-ok response ([#1312](https://github.com/storacha/upload-service/issues/1312)) ([d6978d7](https://github.com/storacha/upload-service/commit/d6978d7ab299be76987c6533d18e6857f6998fe6)) +* **upload-api:** integrate agent store for idempotence & invocation/receipt persistence ([#1444](https://github.com/storacha/upload-service/issues/1444)) ([c9bf33e](https://github.com/storacha/upload-service/commit/c9bf33e5512397a654db933a5e6b5db0c7c22da5)) +* upload-client uploadDirectory, by default, sorts the provided files by file name to help the user call us in a way that is deterministic and minimizes cost ([#1173](https://github.com/storacha/upload-service/issues/1173)) ([8cd2555](https://github.com/storacha/upload-service/commit/8cd2555d901d7e684a9a5cc2516e5a91edd58621)) +* use digest in `blob/accept` location commitment ([#1480](https://github.com/storacha/upload-service/issues/1480)) ([ade45eb](https://github.com/storacha/upload-service/commit/ade45eb6f9b71f4bb4fcc771345ad21e966db730)) + + +### Fixes + +* avoid duplicates on aggregator buffer concat ([#1259](https://github.com/storacha/upload-service/issues/1259)) ([9e64bab](https://github.com/storacha/upload-service/commit/9e64babe93edeb474fc740d9be74c709d47bed1a)) +* check service did in w3filecoin ([#1476](https://github.com/storacha/upload-service/issues/1476)) ([11b00bf](https://github.com/storacha/upload-service/commit/11b00bf880dbbbc40b657d2417a4b13aa8c60a7d)) +* configure max pieces ([#1566](https://github.com/storacha/upload-service/issues/1566)) ([71674ed](https://github.com/storacha/upload-service/commit/71674ed90022f499a144bcc201416e2568bd4d24)) +* dealer offer store keys without space ([#1066](https://github.com/storacha/upload-service/issues/1066)) ([301f411](https://github.com/storacha/upload-service/commit/301f411de74bca6b70c6b867c1bdc724a0a3af20)) +* drop filecoin storefront skip submit queue option ([#1371](https://github.com/storacha/upload-service/issues/1371)) ([1114383](https://github.com/storacha/upload-service/commit/111438395dbd4530fade17b0d216ff056df7d832)) +* enable storefront signer to be different from main service signer ([#1072](https://github.com/storacha/upload-service/issues/1072)) ([21ded3c](https://github.com/storacha/upload-service/commit/21ded3c171ca66480e4f74329943527dcc2bac3e)) +* filecoin test use blob ([#1422](https://github.com/storacha/upload-service/issues/1422)) ([359c0b7](https://github.com/storacha/upload-service/commit/359c0b736cad8e4375d75af4f60e97e20057e7aa)) +* **filecoin-api:** parallel put to piece accept queue ([#1560](https://github.com/storacha/upload-service/issues/1560)) ([e7cbb6d](https://github.com/storacha/upload-service/commit/e7cbb6dc7930b7b19335286bf1908d2ed3cb9437)) +* issue where typedoc docs would only show full docs for w3up-client ([#1141](https://github.com/storacha/upload-service/issues/1141)) ([0b8d3f3](https://github.com/storacha/upload-service/commit/0b8d3f3b52918b1b4d3b76ea6fea3fb0c837cd73)) +* lint ([#1095](https://github.com/storacha/upload-service/issues/1095)) ([f9cc770](https://github.com/storacha/upload-service/commit/f9cc77029d7c0651cb2961d08eca6f94dc1aef6c)) +* migrate repo ([#1389](https://github.com/storacha/upload-service/issues/1389)) ([475a287](https://github.com/storacha/upload-service/commit/475a28743ff9f7138b46dfe4227d3c80ed75a6a2)) +* package metadata ([#1161](https://github.com/storacha/upload-service/issues/1161)) ([b8a1cc2](https://github.com/storacha/upload-service/commit/b8a1cc2e125a91be582998bda295e1ae1caab087)) +* rename blob and index client capabilities ([#1478](https://github.com/storacha/upload-service/issues/1478)) ([17e3a31](https://github.com/storacha/upload-service/commit/17e3a3161c6585b1844abcf7ed27252fa8580870)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* return piece accept receipt error ([#1512](https://github.com/storacha/upload-service/issues/1512)) ([05283cf](https://github.com/storacha/upload-service/commit/05283cfc8ace5e8716d6557a8e29402ef4a2e3c0)) +* revert enable storefront signer to be different from main service signer ([#1075](https://github.com/storacha/upload-service/issues/1075)) ([80cdde0](https://github.com/storacha/upload-service/commit/80cdde0f5b610cf6328dc17cb505759eddda821a)) +* storefront content store rename and separation for test ([#1409](https://github.com/storacha/upload-service/issues/1409)) ([05e5db3](https://github.com/storacha/upload-service/commit/05e5db35544c935a6c8e65e8f27583cffcf224e1)) +* storefront events cron with max concurrency ([#1191](https://github.com/storacha/upload-service/issues/1191)) ([11010c9](https://github.com/storacha/upload-service/commit/11010c94b9682e93b6209a169871021d37b76011)) +* upgrade ucanto core ([#1127](https://github.com/storacha/upload-service/issues/1127)) ([5ce4d22](https://github.com/storacha/upload-service/commit/5ce4d2292d7e980da4a2ea0f1583f608a81157d2)) +* upgrade ucanto libs and format filecoin api ([#1359](https://github.com/storacha/upload-service/issues/1359)) ([87ca098](https://github.com/storacha/upload-service/commit/87ca098186fe204ff3409a2684719f1c54148c97)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) +* use one-webcrypto from npm ([#1525](https://github.com/storacha/upload-service/issues/1525)) ([9345c54](https://github.com/storacha/upload-service/commit/9345c5415bc0b0d6ce8ccdbe92eb155b11835fd8)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* appease linter ([782c6d0](https://github.com/storacha/upload-service/commit/782c6d0b3ca93ee801b38126339a262bcd713ede)) +* **main:** release filecoin-api 4.0.3 ([#1064](https://github.com/storacha/upload-service/issues/1064)) ([ef4ce7a](https://github.com/storacha/upload-service/commit/ef4ce7af0aedcb0b3dfea189260dbe1feecb6d59)) +* **main:** release filecoin-api 4.0.4 ([#1067](https://github.com/storacha/upload-service/issues/1067)) ([c3ed3b9](https://github.com/storacha/upload-service/commit/c3ed3b92af129771af360677dfe761bccd2d399b)) +* **main:** release filecoin-api 4.0.5 ([#1073](https://github.com/storacha/upload-service/issues/1073)) ([9cf2fc0](https://github.com/storacha/upload-service/commit/9cf2fc004463c668ed7d522a83bb9d62372d393e)) +* **main:** release filecoin-api 4.0.6 ([#1077](https://github.com/storacha/upload-service/issues/1077)) ([40d0e7a](https://github.com/storacha/upload-service/commit/40d0e7a97abc4877441168f8ca57753f846e14d5)) +* **main:** release filecoin-api 4.1.0 ([#1085](https://github.com/storacha/upload-service/issues/1085)) ([9b752f9](https://github.com/storacha/upload-service/commit/9b752f993ab93ceb3d41cd71954bd40da9746588)) +* **main:** release filecoin-api 4.1.1 ([#1133](https://github.com/storacha/upload-service/issues/1133)) ([3621b42](https://github.com/storacha/upload-service/commit/3621b4247faac5b96230b68abb767a752bebf79c)) +* **main:** release filecoin-api 4.1.2 ([#1148](https://github.com/storacha/upload-service/issues/1148)) ([fa6405d](https://github.com/storacha/upload-service/commit/fa6405d419370985deb69a24a51566dc72a2c7d8)) +* **main:** release filecoin-api 4.2.0 ([#1164](https://github.com/storacha/upload-service/issues/1164)) ([dfdf762](https://github.com/storacha/upload-service/commit/dfdf762a505aba2912b449ab1e5fa4d67f00b4f9)) +* **main:** release filecoin-api 4.3.0 ([#1194](https://github.com/storacha/upload-service/issues/1194)) ([a1aa231](https://github.com/storacha/upload-service/commit/a1aa231cbadec5ed4c58a7573276140385887c79)) +* **main:** release filecoin-api 4.3.1 ([#1205](https://github.com/storacha/upload-service/issues/1205)) ([7f42f39](https://github.com/storacha/upload-service/commit/7f42f394f25b4b00c3fa66c3e911556d46743019)) +* **main:** release filecoin-api 4.4.0 ([#1303](https://github.com/storacha/upload-service/issues/1303)) ([bb74ffc](https://github.com/storacha/upload-service/commit/bb74ffca4ae6f7b2bd9e20f9aa5c9ff081b6962f)) +* **main:** release filecoin-api 4.5.0 ([#1314](https://github.com/storacha/upload-service/issues/1314)) ([d31ff06](https://github.com/storacha/upload-service/commit/d31ff06931d3a38b17182927effbcdaff9ceaefe)) +* **main:** release filecoin-api 4.6.0 ([#1346](https://github.com/storacha/upload-service/issues/1346)) ([4b166fd](https://github.com/storacha/upload-service/commit/4b166fd0424bd10067de26bc88e069cce2631333)) +* **main:** release filecoin-api 4.6.1 ([#1363](https://github.com/storacha/upload-service/issues/1363)) ([efcb912](https://github.com/storacha/upload-service/commit/efcb912d01c5d15e4a1876e80031d563506939e4)) +* **main:** release filecoin-api 5.0.0 ([#1384](https://github.com/storacha/upload-service/issues/1384)) ([cb5b628](https://github.com/storacha/upload-service/commit/cb5b628a7f9097ce295b71c34f1cdd33830340b0)) +* **main:** release filecoin-api 5.0.1 ([#1398](https://github.com/storacha/upload-service/issues/1398)) ([2e3ef61](https://github.com/storacha/upload-service/commit/2e3ef6180fde897c5f5b583408e443909c0c91ba)) +* **main:** release filecoin-api 6.0.0 ([#1414](https://github.com/storacha/upload-service/issues/1414)) ([939e839](https://github.com/storacha/upload-service/commit/939e839fbcd80131300b2ed302ba8b3250cac13b)) +* **main:** release filecoin-api 6.0.1 ([#1424](https://github.com/storacha/upload-service/issues/1424)) ([f8c6c1d](https://github.com/storacha/upload-service/commit/f8c6c1d258f1bab1dfe296a083a5440981eae3ad)) +* **main:** release filecoin-api 7.0.0 ([#1430](https://github.com/storacha/upload-service/issues/1430)) ([604d300](https://github.com/storacha/upload-service/commit/604d300dde17521eea7333b949bb3f6796bd80a2)) +* **main:** release filecoin-api 7.1.0 ([#1481](https://github.com/storacha/upload-service/issues/1481)) ([9d38080](https://github.com/storacha/upload-service/commit/9d3808025286c51c0be481839988c2f44584a2db)) +* **main:** release filecoin-api 7.1.1 ([#1513](https://github.com/storacha/upload-service/issues/1513)) ([d4f5f45](https://github.com/storacha/upload-service/commit/d4f5f45c4f532769b38f9fb784bebc0e75181b8e)) +* **main:** release filecoin-api 7.2.0 ([#1522](https://github.com/storacha/upload-service/issues/1522)) ([0aebf9f](https://github.com/storacha/upload-service/commit/0aebf9ff97e7c6291db86d61a81f9c41276b5105)) +* **main:** release filecoin-api 7.2.1 ([#1528](https://github.com/storacha/upload-service/issues/1528)) ([5b8e148](https://github.com/storacha/upload-service/commit/5b8e148d03ee81118c01cab504cc3d7a4a35db83)) +* **main:** release filecoin-api 7.3.0 ([#1540](https://github.com/storacha/upload-service/issues/1540)) ([77b31e9](https://github.com/storacha/upload-service/commit/77b31e93d50876dc547a027f408b6db9273b1502)) +* **main:** release filecoin-api 7.3.1 ([#1561](https://github.com/storacha/upload-service/issues/1561)) ([61d408a](https://github.com/storacha/upload-service/commit/61d408a2ecd61ca81a758d4e0b30f1ed0c3b77e8)) +* **main:** release filecoin-api 7.3.2 ([#1567](https://github.com/storacha/upload-service/issues/1567)) ([534d3be](https://github.com/storacha/upload-service/commit/534d3beff2b46adc60653a4f3691be959d36aed6)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [7.3.2](https://github.com/storacha/w3up/compare/filecoin-api-v7.3.1...filecoin-api-v7.3.2) (2024-10-20) diff --git a/packages/filecoin-api/package.json b/packages/filecoin-api/package.json index 41f260151..d61d52f48 100644 --- a/packages/filecoin-api/package.json +++ b/packages/filecoin-api/package.json @@ -1,12 +1,12 @@ { - "name": "@web3-storage/filecoin-api", - "version": "7.3.2", + "name": "@storacha/filecoin-api", + "version": "1.1.1", "type": "module", "main": "./src/lib.js", - "homepage": "https://web3.storage", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/filecoin-api" }, "files": [ @@ -154,36 +154,36 @@ "coverage": "c8 -r text -r html npm run test" }, "dependencies": { - "@ipld/dag-ucan": "^3.4.0", + "@ipld/dag-ucan": "^3.4.5", + "@storacha/capabilities": "workspace:^", "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/server": "^10.0.0", + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/server": "^10.1.0", "@ucanto/transport": "^9.1.1", - "@web3-storage/capabilities": "workspace:^", "@web3-storage/content-claims": "^5.0.0", "@web3-storage/data-segment": "^5.2.0", "fr32-sha2-256-trunc254-padded-binary-tree-multihash": "^3.3.0", "p-map": "^6.0.0" }, "devDependencies": { + "@storacha/eslint-config": "workspace:^", + "@storacha/filecoin-client": "workspace:^", "@storacha/one-webcrypto": "^1.0.1", "@types/assert": "^1.5.10", "@types/mocha": "^10.0.1", "@ucanto/client": "^9.0.1", - "@ucanto/principal": "^9.0.1", + "@ucanto/principal": "^9.0.2", "@web-std/blob": "^3.0.5", - "@web3-storage/eslint-config-w3up": "workspace:^", - "@web3-storage/filecoin-client": "workspace:^", "c8": "^10.1.2", "mocha": "^10.2.0", - "multiformats": "^12.1.2", + "multiformats": "^13.3.1", "p-wait-for": "^5.0.2", "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -213,7 +213,7 @@ "ignores": [ "dist", "@types/*", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] }, "engines": { diff --git a/packages/filecoin-api/src/aggregator/api.ts b/packages/filecoin-api/src/aggregator/api.ts index 9b3b639a0..f38435fb6 100644 --- a/packages/filecoin-api/src/aggregator/api.ts +++ b/packages/filecoin-api/src/aggregator/api.ts @@ -1,10 +1,10 @@ import type { Signer, Principal, Link } from '@ucanto/interface' -import { InclusionProof } from '@web3-storage/capabilities/types' +import { InclusionProof } from '@storacha/capabilities/types' import { PieceLink, API as DataSegmentAPI } from '@web3-storage/data-segment' import { AggregatorService, DealerService, -} from '@web3-storage/filecoin-client/types' +} from '@storacha/filecoin-client/types' import { Store, UpdatableStore, diff --git a/packages/filecoin-api/src/aggregator/buffer-reducing.js b/packages/filecoin-api/src/aggregator/buffer-reducing.js index ce695ebcd..549c5bcad 100644 --- a/packages/filecoin-api/src/aggregator/buffer-reducing.js +++ b/packages/filecoin-api/src/aggregator/buffer-reducing.js @@ -208,13 +208,17 @@ export function aggregatePieces(bufferedPieces, config) { builder.offset * BigInt(NODE_SIZE) + BigInt(builder.limit) * BigInt(Index.EntrySize) - console.log(`Used ${totalUsedSpace} bytes in ${addedBufferedPieces.length} pieces (min ${config.minAggregateSize} bytes)`) + console.log( + `Used ${totalUsedSpace} bytes in ${addedBufferedPieces.length} pieces (min ${config.minAggregateSize} bytes)` + ) // If not enough space return undefined if (totalUsedSpace < BigInt(config.minAggregateSize)) { // ...but only if not exceeded max aggregate pieces if (addedBufferedPieces.length === config.maxAggregatePieces) { - console.warn(`Building aggregate: max allowed pieces reached (${config.maxAggregatePieces})`) + console.warn( + `Building aggregate: max allowed pieces reached (${config.maxAggregatePieces})` + ) } else { return console.log('Not enough data for aggregate.') } diff --git a/packages/filecoin-api/src/aggregator/events.js b/packages/filecoin-api/src/aggregator/events.js index 11e054731..ee4d2e17e 100644 --- a/packages/filecoin-api/src/aggregator/events.js +++ b/packages/filecoin-api/src/aggregator/events.js @@ -1,4 +1,4 @@ -import { Aggregator, Dealer } from '@web3-storage/filecoin-client' +import { Aggregator, Dealer } from '@storacha/filecoin-client' import { Aggregate, Piece } from '@web3-storage/data-segment' import { CBOR } from '@ucanto/core' import map from 'p-map' @@ -229,7 +229,10 @@ export const handleAggregateInsertToPieceAcceptQueue = async ( // TODO: Batch per a maximum to queue const results = await map( pieces, - /** @returns {Promise>} */ + /** + * @param piece + * @returns {Promise>} + */ async piece => { const inclusionProof = aggregateBuilder.resolveProof(piece.link) if (inclusionProof.error) return inclusionProof diff --git a/packages/filecoin-api/src/aggregator/service.js b/packages/filecoin-api/src/aggregator/service.js index 56b013f6f..797cbdb83 100644 --- a/packages/filecoin-api/src/aggregator/service.js +++ b/packages/filecoin-api/src/aggregator/service.js @@ -1,8 +1,8 @@ import * as Server from '@ucanto/server' import * as Client from '@ucanto/client' import * as CAR from '@ucanto/transport/car' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' // eslint-disable-next-line no-unused-vars import * as API from '../types.js' import { diff --git a/packages/filecoin-api/src/deal-tracker/service.js b/packages/filecoin-api/src/deal-tracker/service.js index 0c8ac50cb..6865bb2d9 100644 --- a/packages/filecoin-api/src/deal-tracker/service.js +++ b/packages/filecoin-api/src/deal-tracker/service.js @@ -1,14 +1,14 @@ import * as Server from '@ucanto/server' import * as Client from '@ucanto/client' import * as CAR from '@ucanto/transport/car' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' // eslint-disable-next-line no-unused-vars import * as API from '../types.js' import { StoreOperationFailed } from '../errors.js' /** - * @typedef {import('@web3-storage/capabilities/types').DealDetails} DealDetails + * @typedef {import('@storacha/capabilities/types').DealDetails} DealDetails */ /** diff --git a/packages/filecoin-api/src/dealer/api.ts b/packages/filecoin-api/src/dealer/api.ts index 8ecd73ea2..aa3505864 100644 --- a/packages/filecoin-api/src/dealer/api.ts +++ b/packages/filecoin-api/src/dealer/api.ts @@ -3,7 +3,7 @@ import { PieceLink } from '@web3-storage/data-segment' import { DealerService, DealTrackerService, -} from '@web3-storage/filecoin-client/types' +} from '@storacha/filecoin-client/types' import { Store, UpdatableStore, diff --git a/packages/filecoin-api/src/dealer/events.js b/packages/filecoin-api/src/dealer/events.js index bd18e3b41..ba6773e85 100644 --- a/packages/filecoin-api/src/dealer/events.js +++ b/packages/filecoin-api/src/dealer/events.js @@ -1,4 +1,4 @@ -import { Dealer, DealTracker } from '@web3-storage/filecoin-client' +import { Dealer, DealTracker } from '@storacha/filecoin-client' import { StoreOperationFailed } from '../errors.js' @@ -120,7 +120,7 @@ export const handleCronTick = async (context) => { * @param {AggregateRecord} context.deal * @param {import('../types.js').UpdatableStore} context.aggregateStore * @param {import('@ucanto/interface').ConnectionView} context.dealTrackerServiceConnection - * @param {import('@web3-storage/filecoin-client/types').InvocationConfig} context.dealTrackerInvocationConfig + * @param {import('@storacha/filecoin-client/types').InvocationConfig} context.dealTrackerInvocationConfig */ async function updateApprovedDeals({ deal, diff --git a/packages/filecoin-api/src/dealer/service.js b/packages/filecoin-api/src/dealer/service.js index 9ae4d6548..831dc2c29 100644 --- a/packages/filecoin-api/src/dealer/service.js +++ b/packages/filecoin-api/src/dealer/service.js @@ -4,8 +4,8 @@ import * as CAR from '@ucanto/transport/car' import { CBOR } from '@ucanto/core' import { sha256 } from 'multiformats/hashes/sha2' import * as Block from 'multiformats/block' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' -import { DealTracker } from '@web3-storage/filecoin-client' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' +import { DealTracker } from '@storacha/filecoin-client' // eslint-disable-next-line no-unused-vars import * as API from '../types.js' import { diff --git a/packages/filecoin-api/src/storefront/api.ts b/packages/filecoin-api/src/storefront/api.ts index cdfc71c11..b1c3f8cef 100644 --- a/packages/filecoin-api/src/storefront/api.ts +++ b/packages/filecoin-api/src/storefront/api.ts @@ -15,7 +15,7 @@ import { AggregatorService, StorefrontService, DealTrackerService, -} from '@web3-storage/filecoin-client/types' +} from '@storacha/filecoin-client/types' import { Store, UpdatableStore, diff --git a/packages/filecoin-api/src/storefront/events.js b/packages/filecoin-api/src/storefront/events.js index c3154ff39..7bf7b6bc3 100644 --- a/packages/filecoin-api/src/storefront/events.js +++ b/packages/filecoin-api/src/storefront/events.js @@ -1,5 +1,5 @@ -import { Storefront, Aggregator } from '@web3-storage/filecoin-client' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' +import { Storefront, Aggregator } from '@storacha/filecoin-client' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' import { Assert } from '@web3-storage/content-claims/capability' import { computePieceCid } from './piece.js' diff --git a/packages/filecoin-api/src/storefront/service.js b/packages/filecoin-api/src/storefront/service.js index 5bc36b511..fc0de53d7 100644 --- a/packages/filecoin-api/src/storefront/service.js +++ b/packages/filecoin-api/src/storefront/service.js @@ -1,9 +1,9 @@ import * as Server from '@ucanto/server' import * as Client from '@ucanto/client' import * as CAR from '@ucanto/transport/car' -import * as StorefrontCaps from '@web3-storage/capabilities/filecoin/storefront' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' -import { DealTracker } from '@web3-storage/filecoin-client' +import * as StorefrontCaps from '@storacha/capabilities/filecoin/storefront' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' +import { DealTracker } from '@storacha/filecoin-client' // eslint-disable-next-line no-unused-vars import * as API from '../types.js' import { diff --git a/packages/filecoin-api/src/types.ts b/packages/filecoin-api/src/types.ts index ca6b49b08..4c24b66dc 100644 --- a/packages/filecoin-api/src/types.ts +++ b/packages/filecoin-api/src/types.ts @@ -12,12 +12,12 @@ import type { ConnectionView, } from '@ucanto/interface' import type { ProviderInput } from '@ucanto/server' -import { InvocationConfig } from '@web3-storage/filecoin-client/types' +import { InvocationConfig } from '@storacha/filecoin-client/types' export * as UcantoInterface from '@ucanto/interface' export type { Result, Variant } from '@ucanto/interface' -export * from '@web3-storage/filecoin-client/types' -export * from '@web3-storage/capabilities/types' +export * from '@storacha/filecoin-client/types' +export * from '@storacha/capabilities/types' // Resources export interface Queue { diff --git a/packages/filecoin-api/test/context/receipts.js b/packages/filecoin-api/test/context/receipts.js index d380827d7..28430c57f 100644 --- a/packages/filecoin-api/test/context/receipts.js +++ b/packages/filecoin-api/test/context/receipts.js @@ -1,7 +1,7 @@ import { Receipt } from '@ucanto/core' -import * as StorefrontCaps from '@web3-storage/capabilities/filecoin/storefront' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' +import * as StorefrontCaps from '@storacha/capabilities/filecoin/storefront' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' import * as API from '../../src/types.js' diff --git a/packages/filecoin-api/test/context/service.js b/packages/filecoin-api/test/context/service.js index 37de7be45..99ef16d43 100644 --- a/packages/filecoin-api/test/context/service.js +++ b/packages/filecoin-api/test/context/service.js @@ -3,10 +3,10 @@ import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import { Assert } from '@web3-storage/content-claims/capability' -import * as StorefrontCaps from '@web3-storage/capabilities/filecoin/storefront' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as StorefrontCaps from '@storacha/capabilities/filecoin/storefront' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' // eslint-disable-next-line no-unused-vars import * as API from '../../src/types.js' diff --git a/packages/filecoin-api/test/context/store-implementations.js b/packages/filecoin-api/test/context/store-implementations.js index 078401f20..1cc370bfa 100644 --- a/packages/filecoin-api/test/context/store-implementations.js +++ b/packages/filecoin-api/test/context/store-implementations.js @@ -17,7 +17,9 @@ export const getStoreImplementations = () => ({ queryFn: (items, search, options) => { const results = Array.from(items) .filter((i) => i.insertedAt > (options?.cursor ?? '')) - .filter((i) => search.status ? i.status === search.status : true) + .filter((i) => + search.status ? i.status === search.status : true + ) .sort((a, b) => (a.insertedAt > b.insertedAt ? 1 : -1)) .slice(0, options?.size ?? items.size) return { results, cursor: results.at(-1)?.insertedAt } @@ -208,7 +210,7 @@ export const getStoreImplementations = () => ({ return nItem }, }) - ), + ) ), }, dealTracker: { diff --git a/packages/filecoin-api/test/events/aggregator.js b/packages/filecoin-api/test/events/aggregator.js index f7b55f069..2b4724789 100644 --- a/packages/filecoin-api/test/events/aggregator.js +++ b/packages/filecoin-api/test/events/aggregator.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' import pWaitFor from 'p-wait-for' import { CBOR } from '@ucanto/core' @@ -586,7 +586,10 @@ export const test = { })) ) assert.ok(handledMessageRes.ok) - assert.equal(handledMessageRes.ok?.aggregatedPieces, config.maxAggregatePieces) + assert.equal( + handledMessageRes.ok?.aggregatedPieces, + config.maxAggregatePieces + ) await pWaitFor( () => diff --git a/packages/filecoin-api/test/events/dealer.js b/packages/filecoin-api/test/events/dealer.js index 727bd9e3e..abca2ef66 100644 --- a/packages/filecoin-api/test/events/dealer.js +++ b/packages/filecoin-api/test/events/dealer.js @@ -1,8 +1,8 @@ import { CBOR } from '@ucanto/core' import * as Signer from '@ucanto/principal/ed25519' import * as Server from '@ucanto/server' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' import * as API from '../../src/types.js' import * as TestAPI from '../types.js' diff --git a/packages/filecoin-api/test/events/storefront.js b/packages/filecoin-api/test/events/storefront.js index fbc27bad3..3aa2f33d4 100644 --- a/packages/filecoin-api/test/events/storefront.js +++ b/packages/filecoin-api/test/events/storefront.js @@ -1,7 +1,7 @@ import * as Server from '@ucanto/server' import * as Signer from '@ucanto/principal/ed25519' import { CBOR } from '@ucanto/core' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' import * as API from '../../src/types.js' import * as TestAPI from '../types.js' diff --git a/packages/filecoin-api/test/services/aggregator.js b/packages/filecoin-api/test/services/aggregator.js index 886c32d4d..e09774014 100644 --- a/packages/filecoin-api/test/services/aggregator.js +++ b/packages/filecoin-api/test/services/aggregator.js @@ -1,5 +1,5 @@ -import { Aggregator } from '@web3-storage/capabilities' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' +import { Aggregator } from '@storacha/capabilities' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' import * as Signer from '@ucanto/principal/ed25519' import { CBOR } from '@ucanto/core' import pWaitFor from 'p-wait-for' @@ -44,7 +44,7 @@ export const test = { // Generate piece for test const [cargo] = await randomCargo(1, 128) - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' // storefront invocation const pieceAddInv = Aggregator.pieceOffer.invoke({ @@ -103,7 +103,7 @@ export const test = { // Generate piece for test const [cargo] = await randomCargo(1, 128) - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' // Store piece into store const putRes = await context.pieceStore.put({ @@ -165,7 +165,7 @@ export const test = { // Generate piece for test const [cargo] = await randomCargo(1, 128) - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' // storefront invocation const pieceAddInv = Aggregator.pieceOffer.invoke({ @@ -198,7 +198,7 @@ export const test = { // Generate piece for test const [cargo] = await randomCargo(1, 128) - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' // storefront invocation const pieceAddInv = Aggregator.pieceOffer.invoke({ diff --git a/packages/filecoin-api/test/services/deal-tracker.js b/packages/filecoin-api/test/services/deal-tracker.js index 6e6face2a..ad3a2ca3f 100644 --- a/packages/filecoin-api/test/services/deal-tracker.js +++ b/packages/filecoin-api/test/services/deal-tracker.js @@ -1,4 +1,4 @@ -import { DealTracker } from '@web3-storage/capabilities' +import { DealTracker } from '@storacha/capabilities' import * as Signer from '@ucanto/principal/ed25519' import * as API from '../../src/types.js' diff --git a/packages/filecoin-api/test/services/dealer.js b/packages/filecoin-api/test/services/dealer.js index 8e9bb743f..92a54ed0e 100644 --- a/packages/filecoin-api/test/services/dealer.js +++ b/packages/filecoin-api/test/services/dealer.js @@ -1,7 +1,7 @@ -import { Dealer } from '@web3-storage/capabilities' +import { Dealer } from '@storacha/capabilities' import * as Signer from '@ucanto/principal/ed25519' import * as Server from '@ucanto/server' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' import { CBOR } from '@ucanto/core' import * as API from '../../src/types.js' diff --git a/packages/filecoin-api/test/services/storefront.js b/packages/filecoin-api/test/services/storefront.js index 18bd1361c..75468351b 100644 --- a/packages/filecoin-api/test/services/storefront.js +++ b/packages/filecoin-api/test/services/storefront.js @@ -1,8 +1,8 @@ -import { Filecoin, Aggregator } from '@web3-storage/capabilities' +import { Filecoin, Aggregator } from '@storacha/capabilities' import * as Server from '@ucanto/server' import { CBOR } from '@ucanto/core' import * as Signer from '@ucanto/principal/ed25519' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' import pWaitFor from 'p-wait-for' import * as API from '../../src/types.js' diff --git a/packages/filecoin-client/CHANGELOG.md b/packages/filecoin-client/CHANGELOG.md index bec02484b..183303b35 100644 --- a/packages/filecoin-client/CHANGELOG.md +++ b/packages/filecoin-client/CHANGELOG.md @@ -1,5 +1,62 @@ # Changelog +## [1.0.2](https://github.com/storacha/upload-service/compare/filecoin-client-v1.0.1...filecoin-client-v1.0.2) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/filecoin-client-v1.0.0...filecoin-client-v1.0.1) (2024-12-19) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## 1.0.0 (2024-12-02) + + +### Features + +* filecoin info ([#1091](https://github.com/storacha/upload-service/issues/1091)) ([adb2442](https://github.com/storacha/upload-service/commit/adb24424d1faf50daf2339b77c22fdd44faa236a)) +* move aggregate information out of deals in filecoin/info ([#1192](https://github.com/storacha/upload-service/issues/1192)) ([18dc590](https://github.com/storacha/upload-service/commit/18dc590ad50a023ef3094bfc1a2d729459e5d68e)) +* router ([#11](https://github.com/storacha/upload-service/issues/11)) ([c810735](https://github.com/storacha/upload-service/commit/c8107354da663120228f779814eafa0c9a3e80a2)) +* upgrade ucanto/transport to 9.1.0 in all packages to get more verbose errors from HTTP transport on non-ok response ([#1312](https://github.com/storacha/upload-service/issues/1312)) ([d6978d7](https://github.com/storacha/upload-service/commit/d6978d7ab299be76987c6533d18e6857f6998fe6)) + + +### Fixes + +* filecoin test use blob ([#1422](https://github.com/storacha/upload-service/issues/1422)) ([359c0b7](https://github.com/storacha/upload-service/commit/359c0b736cad8e4375d75af4f60e97e20057e7aa)) +* issue where typedoc docs would only show full docs for w3up-client ([#1141](https://github.com/storacha/upload-service/issues/1141)) ([0b8d3f3](https://github.com/storacha/upload-service/commit/0b8d3f3b52918b1b4d3b76ea6fea3fb0c837cd73)) +* migrate repo ([#1389](https://github.com/storacha/upload-service/issues/1389)) ([475a287](https://github.com/storacha/upload-service/commit/475a28743ff9f7138b46dfe4227d3c80ed75a6a2)) +* package metadata ([#1161](https://github.com/storacha/upload-service/issues/1161)) ([b8a1cc2](https://github.com/storacha/upload-service/commit/b8a1cc2e125a91be582998bda295e1ae1caab087)) +* repo URLs ([#1550](https://github.com/storacha/upload-service/issues/1550)) ([e02ddf3](https://github.com/storacha/upload-service/commit/e02ddf3696553b03f8d2f7316de0a99a9303a60f)) +* upgrade filecoin client deal tracker principal ([#1092](https://github.com/storacha/upload-service/issues/1092)) ([cde7113](https://github.com/storacha/upload-service/commit/cde71134ab8fdd4a72e3764da30ae0a414a8690b)) +* upgrade ucanto core ([#1127](https://github.com/storacha/upload-service/issues/1127)) ([5ce4d22](https://github.com/storacha/upload-service/commit/5ce4d2292d7e980da4a2ea0f1583f608a81157d2)) +* upgrade ucanto libs and format filecoin api ([#1359](https://github.com/storacha/upload-service/issues/1359)) ([87ca098](https://github.com/storacha/upload-service/commit/87ca098186fe204ff3409a2684719f1c54148c97)) +* upload API test fixes ([6b0d72d](https://github.com/storacha/upload-service/commit/6b0d72dee3dc9ce5320ad8de333a718d644b5c3d)) + + +### Other Changes + +* Add `pnpm dev` to watch-build all packages ([#1533](https://github.com/storacha/upload-service/issues/1533)) ([07970ef](https://github.com/storacha/upload-service/commit/07970efd443149158ebbfb2c4e745b5007eb9407)) +* **main:** release filecoin-client 3.0.2 ([#1093](https://github.com/storacha/upload-service/issues/1093)) ([7896e73](https://github.com/storacha/upload-service/commit/7896e73801d2fae29c0288d5e96642f92c64a296)) +* **main:** release filecoin-client 3.1.0 ([#1097](https://github.com/storacha/upload-service/issues/1097)) ([2cbc76d](https://github.com/storacha/upload-service/commit/2cbc76d115c706248bec6cb8e66139dd032c28d2)) +* **main:** release filecoin-client 3.1.1 ([#1130](https://github.com/storacha/upload-service/issues/1130)) ([afd9306](https://github.com/storacha/upload-service/commit/afd9306f6f2e99e1ef55e186521b4de4e86281b2)) +* **main:** release filecoin-client 3.1.2 ([#1146](https://github.com/storacha/upload-service/issues/1146)) ([824b29d](https://github.com/storacha/upload-service/commit/824b29d60db0f19fc539bca96c3adbbcc1343da2)) +* **main:** release filecoin-client 3.1.3 ([#1162](https://github.com/storacha/upload-service/issues/1162)) ([26fde82](https://github.com/storacha/upload-service/commit/26fde82e5d742e3f190af4a4929cf07962179273)) +* **main:** release filecoin-client 3.2.0 ([#1197](https://github.com/storacha/upload-service/issues/1197)) ([85e4b87](https://github.com/storacha/upload-service/commit/85e4b870bc0313e0e866082e4572d7584164edcf)) +* **main:** release filecoin-client 3.3.0 ([#1317](https://github.com/storacha/upload-service/issues/1317)) ([08a8bab](https://github.com/storacha/upload-service/commit/08a8babc3afb0208f4ebac03a99060d0cae279c9)) +* **main:** release filecoin-client 3.3.1 ([#1361](https://github.com/storacha/upload-service/issues/1361)) ([1c95471](https://github.com/storacha/upload-service/commit/1c9547196c6a1818f6de9bbec1d17236aacde4b2)) +* **main:** release filecoin-client 3.3.2 ([#1397](https://github.com/storacha/upload-service/issues/1397)) ([37f1ffd](https://github.com/storacha/upload-service/commit/37f1ffd638e9498b78bcf444e87182e1599e7b92)) +* **main:** release filecoin-client 3.3.3 ([#1423](https://github.com/storacha/upload-service/issues/1423)) ([6af72b0](https://github.com/storacha/upload-service/commit/6af72b0aadc70ab4bed700d7f3df09dc087e75b1)) +* **main:** release filecoin-client 3.3.4 ([#1539](https://github.com/storacha/upload-service/issues/1539)) ([a3af226](https://github.com/storacha/upload-service/commit/a3af22678b45365fa951d88d9251bf6e0d0d65b2)) +* package renames ([0f797ed](https://github.com/storacha/upload-service/commit/0f797ed298b570dd649aa18055f801b0ab6fbfd8)) + ## [3.3.4](https://github.com/storacha/w3up/compare/filecoin-client-v3.3.3...filecoin-client-v3.3.4) (2024-09-23) diff --git a/packages/filecoin-client/README.md b/packages/filecoin-client/README.md index 2ba22d04e..d953a34c6 100644 --- a/packages/filecoin-client/README.md +++ b/packages/filecoin-client/README.md @@ -1,16 +1,16 @@ -


web3.storage

-

The w3filecoin client for https://web3.storage

+


storacha.network

+

The w3filecoin client for https://storacha.network

## About -The `@web3-storage/filecoin-client` package provides the "low level" client API to make data uploaded with the w3up platform available in Filecoin Storage providers. It is based on [storacha/specs/w3-filecoin.md](https://github.com/storacha/specs/blob/main/w3-filecoin.md) and is not intended for web3.storage end users. +The `@storacha/filecoin-client` package provides the "low level" client API to make data uploaded with the w3up platform available in Filecoin Storage providers. It is based on [storacha/specs/w3-filecoin.md](https://github.com/storacha/specs/blob/main/w3-filecoin.md) and is not intended for storacha.network end users. ## Install Install the package using npm: ```bash -npm install @web3-storage/filecoin-client +npm install @storacha/filecoin-client ``` ## Usage @@ -24,7 +24,7 @@ A receipt for successful execution will contain an effect, linking to a `filecoi Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Storefront } from '@web3-storage/filecoin-client' +import { Storefront } from '@storacha/filecoin-client' const res = await Storefront.filecoinOffer( invocationConfig, @@ -52,7 +52,7 @@ A receipt for successful execution indicates that the offered piece has been sub Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Storefront } from '@web3-storage/filecoin-client' +import { Storefront } from '@storacha/filecoin-client' const res = await Storefront.filecoinSubmit( invocationConfig, @@ -80,7 +80,7 @@ A receipt for successful execution indicates that the offered piece has been acc Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Storefront } from '@web3-storage/filecoin-client' +import { Storefront } from '@storacha/filecoin-client' const res = await Storefront.filecoinAccept( invocationConfig, @@ -108,7 +108,7 @@ A receipt for successful execution will contain an effect, linking to a `piece/a Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Aggregator } from '@web3-storage/filecoin-client' +import { Aggregator } from '@storacha/filecoin-client' const res = await Aggregator.pieceOffer( invocationConfig, @@ -136,7 +136,7 @@ A receipt for successful execution indicates that the offered piece was included Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Aggregator } from '@web3-storage/filecoin-client' +import { Aggregator } from '@storacha/filecoin-client' const res = await Aggregator.pieceAccept( invocationConfig, @@ -164,7 +164,7 @@ A receipt for successful execution will contain an effect, linking to an `aggreg Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { Dealer } from '@web3-storage/filecoin-client' +import { Dealer } from '@storacha/filecoin-client' const res = await Dealer.aggregateOffer( invocationConfig, @@ -192,7 +192,7 @@ A receipt for successful execution indicates that an aggregate has been accepted Otherwise the task is failed and the receipt will contain details of the reason behind the failure, as well as multiple effects, linking to `piece/offer` tasks that will retry _valid_ pieces and complete asynchronously. ```js -import { Dealer } from '@web3-storage/filecoin-client' +import { Dealer } from '@storacha/filecoin-client' const res = await Dealer.aggregateAccept( invocationConfig, @@ -220,7 +220,7 @@ A receipt for successful execution will contain details of deals the provided pi Otherwise the task is failed and the receipt will contain details of the reason behind the failure. ```js -import { DealTracker } from '@web3-storage/filecoin-client' +import { DealTracker } from '@storacha/filecoin-client' const add = await DealTracker.dealInfo( invocationConfig, @@ -250,9 +250,9 @@ This is the configuration for the UCAN invocation. It is an object with `issuer` ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/license.md) +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/license.md) diff --git a/packages/filecoin-client/package.json b/packages/filecoin-client/package.json index cdd5d13c5..d6c7145f7 100644 --- a/packages/filecoin-client/package.json +++ b/packages/filecoin-client/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/filecoin-client", - "version": "3.3.4", - "description": "The w3filecoin client for web3.storage", - "homepage": "https://web3.storage", + "name": "@storacha/filecoin-client", + "version": "1.0.2", + "description": "The w3filecoin client for storacha.network", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/w3filecoin-client" }, "author": "Vasco Santos", @@ -54,33 +54,33 @@ "dist/src/**/*.d.ts.map" ], "dependencies": { - "@ipld/dag-ucan": "^3.4.0", + "@ipld/dag-ucan": "^3.4.5", + "@storacha/capabilities": "workspace:^", "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/transport": "^9.1.1", - "@web3-storage/capabilities": "workspace:^" + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/transport": "^9.1.1" }, "devDependencies": { "@ipld/dag-json": "^10.1.4", + "@storacha/eslint-config": "workspace:^", "@types/assert": "^1.5.6", "@types/mocha": "^10.0.1", - "@ucanto/principal": "^9.0.1", - "@ucanto/server": "^10.0.0", - "@web3-storage/data-segment": "^4.0.0", - "@web3-storage/eslint-config-w3up": "workspace:^", + "@ucanto/principal": "^9.0.2", + "@ucanto/server": "^10.1.0", + "@web3-storage/data-segment": "^5.3.0", "assert": "^2.0.0", "c8": "^7.13.0", "hundreds": "^0.0.9", "mocha": "^10.2.0", - "multiformats": "^12.1.2", + "multiformats": "^13.3.1", "npm-run-all": "^4.1.5", "playwright-test": "^12.3.4", "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -104,7 +104,7 @@ "@types/*", "assert", "c8", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] } } diff --git a/packages/filecoin-client/src/aggregator.js b/packages/filecoin-client/src/aggregator.js index 76eb840af..43a0bedef 100644 --- a/packages/filecoin-client/src/aggregator.js +++ b/packages/filecoin-client/src/aggregator.js @@ -1,6 +1,6 @@ import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' -import * as Aggregator from '@web3-storage/capabilities/filecoin/aggregator' +import * as Aggregator from '@storacha/capabilities/filecoin/aggregator' import { services } from './service.js' /** diff --git a/packages/filecoin-client/src/deal-tracker.js b/packages/filecoin-client/src/deal-tracker.js index 42a07c03d..bebc5301e 100644 --- a/packages/filecoin-client/src/deal-tracker.js +++ b/packages/filecoin-client/src/deal-tracker.js @@ -1,6 +1,6 @@ import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' -import * as DealTracker from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealTracker from '@storacha/capabilities/filecoin/deal-tracker' import { services } from './service.js' /** diff --git a/packages/filecoin-client/src/dealer.js b/packages/filecoin-client/src/dealer.js index 379ace446..f54222f1c 100644 --- a/packages/filecoin-client/src/dealer.js +++ b/packages/filecoin-client/src/dealer.js @@ -1,7 +1,7 @@ import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' import { CBOR } from '@ucanto/core' -import * as Dealer from '@web3-storage/capabilities/filecoin/dealer' +import * as Dealer from '@storacha/capabilities/filecoin/dealer' import { services } from './service.js' /** diff --git a/packages/filecoin-client/src/service.js b/packages/filecoin-client/src/service.js index 161046025..c76639774 100644 --- a/packages/filecoin-client/src/service.js +++ b/packages/filecoin-client/src/service.js @@ -10,19 +10,19 @@ import * as DID from '@ipld/dag-ucan/did' */ export const services = { STOREFRONT: { - url: new URL('https://up.web3.storage'), - principal: DID.parse('did:web:web3.storage'), + url: new URL('https://up.storacha.network'), + principal: DID.parse('did:web:storacha.network'), }, AGGREGATOR: { - url: new URL('https://aggregator.web3.storage'), - principal: DID.parse('did:web:web3.storage'), + url: new URL('https://aggregator.storacha.network'), + principal: DID.parse('did:web:storacha.network'), }, DEALER: { - url: new URL('https://dealer.web3.storage'), - principal: DID.parse('did:web:web3.storage'), + url: new URL('https://dealer.storacha.network'), + principal: DID.parse('did:web:storacha.network'), }, DEAL_TRACKER: { - url: new URL('https://tracker.web3.storage'), - principal: DID.parse('did:web:web3.storage'), + url: new URL('https://tracker.storacha.network'), + principal: DID.parse('did:web:storacha.network'), }, } diff --git a/packages/filecoin-client/src/storefront.js b/packages/filecoin-client/src/storefront.js index 8bcf12011..76484c189 100644 --- a/packages/filecoin-client/src/storefront.js +++ b/packages/filecoin-client/src/storefront.js @@ -1,6 +1,6 @@ import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' -import * as Storefront from '@web3-storage/capabilities/filecoin/storefront' +import * as Storefront from '@storacha/capabilities/filecoin/storefront' import { services } from './service.js' /** diff --git a/packages/filecoin-client/src/types.ts b/packages/filecoin-client/src/types.ts index 752ae4711..27e0d9a12 100644 --- a/packages/filecoin-client/src/types.ts +++ b/packages/filecoin-client/src/types.ts @@ -34,7 +34,7 @@ import { DealInfo, DealInfoSuccess, DealInfoFailure, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' export type SERVICE = 'STOREFRONT' | 'AGGREGATOR' | 'DEALER' | 'DEAL_TRACKER' export interface ServiceConfig { diff --git a/packages/filecoin-client/test/aggregator.test.js b/packages/filecoin-client/test/aggregator.test.js index 11dbbbde8..be0dd8ef0 100644 --- a/packages/filecoin-client/test/aggregator.test.js +++ b/packages/filecoin-client/test/aggregator.test.js @@ -3,7 +3,7 @@ import * as Signer from '@ucanto/principal/ed25519' import * as Client from '@ucanto/client' import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' -import * as AggregatorCaps from '@web3-storage/capabilities/filecoin/aggregator' +import * as AggregatorCaps from '@storacha/capabilities/filecoin/aggregator' import { pieceOffer, pieceAccept } from '../src/aggregator.js' import { randomAggregate, randomCargo } from './helpers/random.js' import { mockService } from './helpers/mocks.js' @@ -16,9 +16,9 @@ describe('aggregator', () => { // Generate cargo to add const [cargo] = await randomCargo(1, 100) - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' - /** @type {import('@web3-storage/capabilities/types').PieceOfferSuccess} */ + /** @type {import('@storacha/capabilities/types').PieceOfferSuccess} */ const pieceOfferResponse = { piece: cargo.link, } @@ -79,7 +79,7 @@ describe('aggregator', () => { it('aggregator accepts a filecoin piece', async () => { const { pieces, aggregate } = await randomAggregate(100, 100) const piece = pieces[0].link - const group = 'did:web:free.web3.storage' + const group = 'did:web:free.storacha.network' // compute proof for piece in aggregate const proof = aggregate.resolveProof(piece) @@ -87,7 +87,7 @@ describe('aggregator', () => { throw new Error('could not compute proof') } - /** @type {import('@web3-storage/capabilities/types').PieceAcceptSuccess} */ + /** @type {import('@storacha/capabilities/types').PieceAcceptSuccess} */ const pieceAcceptResponse = { piece, aggregate: aggregate.link, diff --git a/packages/filecoin-client/test/deal-tracker.test.js b/packages/filecoin-client/test/deal-tracker.test.js index e59dd0273..8a81cf17e 100644 --- a/packages/filecoin-client/test/deal-tracker.test.js +++ b/packages/filecoin-client/test/deal-tracker.test.js @@ -3,7 +3,7 @@ import * as Signer from '@ucanto/principal/ed25519' import * as Client from '@ucanto/client' import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' -import * as DealTrackerCaps from '@web3-storage/capabilities/filecoin/deal-tracker' +import * as DealTrackerCaps from '@storacha/capabilities/filecoin/deal-tracker' import { dealInfo } from '../src/deal-tracker.js' import { randomCargo } from './helpers/random.js' import { mockService } from './helpers/mocks.js' @@ -17,7 +17,7 @@ describe('deal tracker', () => { // Generate cargo to get info const [cargo] = await randomCargo(1, 100) - /** @type {import('@web3-storage/capabilities/types').DealInfoSuccess} */ + /** @type {import('@storacha/capabilities/types').DealInfoSuccess} */ const dealInfoResponse = { deals: { 12_345: { diff --git a/packages/filecoin-client/test/dealer.test.js b/packages/filecoin-client/test/dealer.test.js index 415b0665d..86fd97081 100644 --- a/packages/filecoin-client/test/dealer.test.js +++ b/packages/filecoin-client/test/dealer.test.js @@ -4,7 +4,7 @@ import * as Client from '@ucanto/client' import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import { CBOR } from '@ucanto/core' -import * as DealerCaps from '@web3-storage/capabilities/filecoin/dealer' +import * as DealerCaps from '@storacha/capabilities/filecoin/dealer' import * as dagJSON from '@ipld/dag-json' import { aggregateOffer, aggregateAccept } from '../src/dealer.js' import { randomAggregate } from './helpers/random.js' @@ -18,7 +18,7 @@ describe('dealer', () => { const { pieces, aggregate } = await randomAggregate(100, 100) const offer = pieces.map((p) => p.link) const piecesBlock = await CBOR.write(offer) - /** @type {import('@web3-storage/capabilities/types').AggregateOfferSuccess} */ + /** @type {import('@storacha/capabilities/types').AggregateOfferSuccess} */ const aggregateOfferResponse = { aggregate: aggregate.link, } @@ -85,7 +85,7 @@ describe('dealer', () => { const offer = pieces.map((p) => p.link) const piecesBlock = await CBOR.write(offer) - /** @type {import('@web3-storage/capabilities/types').AggregateAcceptSuccess} */ + /** @type {import('@storacha/capabilities/types').AggregateAcceptSuccess} */ const aggregateAcceptResponse = { dataType: 0n, dataSource: { @@ -143,7 +143,7 @@ describe('dealer', () => { const offer = pieces.map((p) => p.link) const piecesBlock = await CBOR.write(offer) - /** @type {import('@web3-storage/capabilities/types').AggregateAcceptFailure} */ + /** @type {import('@storacha/capabilities/types').AggregateAcceptFailure} */ const aggregateAcceptResponse = { name: 'InvalidPiece', message: 'Aggregate is not a valid piece.', diff --git a/packages/filecoin-client/test/storefront.test.js b/packages/filecoin-client/test/storefront.test.js index 927bdc02f..db6a88f04 100644 --- a/packages/filecoin-client/test/storefront.test.js +++ b/packages/filecoin-client/test/storefront.test.js @@ -3,7 +3,7 @@ import * as Signer from '@ucanto/principal/ed25519' import * as Client from '@ucanto/client' import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' -import * as StorefrontCaps from '@web3-storage/capabilities/filecoin/storefront' +import * as StorefrontCaps from '@storacha/capabilities/filecoin/storefront' import * as dagJSON from '@ipld/dag-json' import { filecoinOffer, @@ -21,7 +21,7 @@ describe('storefront', () => { const { agent } = await getContext() const [cargo] = await randomCargo(1, 100) - /** @type {import('@web3-storage/capabilities/types').FilecoinOfferSuccess} */ + /** @type {import('@storacha/capabilities/types').FilecoinOfferSuccess} */ const filecoinOfferResponse = { piece: cargo.link, } @@ -93,7 +93,7 @@ describe('storefront', () => { it('storefront submits a filecoin piece', async () => { const [cargo] = await randomCargo(1, 100) - /** @type {import('@web3-storage/capabilities/types').FilecoinSubmitSuccess} */ + /** @type {import('@storacha/capabilities/types').FilecoinSubmitSuccess} */ const filecoinSubmitResponse = { piece: cargo.link, } @@ -144,7 +144,7 @@ describe('storefront', () => { throw new Error('could not compute proof') } - /** @type {import('@web3-storage/capabilities/types').FilecoinAcceptSuccess} */ + /** @type {import('@storacha/capabilities/types').FilecoinAcceptSuccess} */ const filecoinAcceptResponse = { aggregate: aggregate.link, piece: cargo.link, @@ -210,7 +210,7 @@ describe('storefront', () => { it('storefront rejects a filecoin piece', async () => { const [cargo] = await randomCargo(1, 100) - /** @type {import('@web3-storage/capabilities/types').FilecoinAcceptFailure} */ + /** @type {import('@storacha/capabilities/types').FilecoinAcceptFailure} */ const filecoinAcceptResponse = { name: 'InvalidContentPiece', message: 'Piece is a bad one.', @@ -267,7 +267,7 @@ describe('storefront', () => { const { agent } = await getContext() const [cargo] = await randomCargo(1, 100) - /** @type {import('@web3-storage/capabilities/types').FilecoinOfferSuccess} */ + /** @type {import('@storacha/capabilities/types').FilecoinOfferSuccess} */ const filecoinOfferResponse = { piece: cargo.link, } diff --git a/packages/upload-api/CHANGELOG.md b/packages/upload-api/CHANGELOG.md index 5c416a221..4b4164568 100644 --- a/packages/upload-api/CHANGELOG.md +++ b/packages/upload-api/CHANGELOG.md @@ -1,5 +1,149 @@ # Changelog +## [1.3.2](https://github.com/storacha/upload-service/compare/upload-api-v1.3.1...upload-api-v1.3.2) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.3.1](https://github.com/storacha/upload-service/compare/upload-api-v1.3.0...upload-api-v1.3.1) (2025-01-20) + + +### Fixes + +* clarify license ([157f93c](https://github.com/storacha/upload-service/commit/157f93c9d36463d5ee420f54f8f4975f345673db)) + +## [1.3.0](https://github.com/storacha/upload-service/compare/upload-api-v1.2.0...upload-api-v1.3.0) (2025-01-20) + + +### Features + +* add legacy handlers ([#117](https://github.com/storacha/upload-service/issues/117)) ([1390106](https://github.com/storacha/upload-service/commit/1390106a3fb16636f00b6f1bf2f1809fc3afe25b)) + +## [1.2.0](https://github.com/storacha/upload-service/compare/upload-api-v1.1.8...upload-api-v1.2.0) (2024-12-19) + + +### Features + +* content serve authorization ([#1590](https://github.com/storacha/upload-service/issues/1590)) + set default gateway ([#99](https://github.com/storacha/upload-service/issues/99)) ([6cbb202](https://github.com/storacha/upload-service/commit/6cbb2027c829189937363b374e258bb1a2b07722)) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## [1.1.8](https://github.com/storacha/upload-service/compare/upload-api-v1.1.7...upload-api-v1.1.8) (2024-12-12) + + +### Fixes + +* **egress/record:** Remove unnecessary multiplication for ts conversion ([#98](https://github.com/storacha/upload-service/issues/98)) ([79ac1ab](https://github.com/storacha/upload-service/commit/79ac1ab7690d10b672c3dfb0ae4ddd9cc420ee2f)) +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([98ab50c](https://github.com/storacha/upload-service/commit/98ab50cf0a5c7985a567e9507b04d948e425d623)) +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([#97](https://github.com/storacha/upload-service/issues/97)) ([df8b9a2](https://github.com/storacha/upload-service/commit/df8b9a2dd88871d33bd836aea431d7dbc2bc590c)) +* **egressRecord:** Remove unnecessary multiplication for ts conversion ([#1588](https://github.com/storacha/upload-service/issues/1588)) ([1870202](https://github.com/storacha/upload-service/commit/1870202f8b2551c4a30488f84530567572382fb0)) + +## [1.1.7](https://github.com/storacha/upload-service/compare/upload-api-v1.1.6...upload-api-v1.1.7) (2024-11-27) + + +### Other Changes + +* trigger release ([8f86297](https://github.com/storacha/upload-service/commit/8f862970d5d7e9f9f62d4c58e3537f8d93135964)) + +## [1.1.6](https://github.com/storacha/upload-service/compare/upload-api-v1.1.5...upload-api-v1.1.6) (2024-11-27) + + +### Other Changes + +* trigger release ([1e10042](https://github.com/storacha/upload-service/commit/1e100425187c0a6523d54bbf97203f323d7a6156)) + +## [1.1.5](https://github.com/storacha/upload-service/compare/upload-api-v1.1.4...upload-api-v1.1.5) (2024-11-27) + + +### Other Changes + +* trigger release ([139afff](https://github.com/storacha/upload-service/commit/139afffa8134165f3774e799e098094fa20fe1ba)) + +## [1.1.4](https://github.com/storacha/upload-service/compare/upload-api-v1.1.3...upload-api-v1.1.4) (2024-11-27) + + +### Fixes + +* compatibility with legacy w3up client ([#59](https://github.com/storacha/upload-service/issues/59)) ([7185046](https://github.com/storacha/upload-service/commit/7185046e3186bef9b4f56f9e6c1c94a0c576fc53)) + +## [1.1.3](https://github.com/storacha/upload-service/compare/upload-api-v1.1.2...upload-api-v1.1.3) (2024-11-12) + + +### Fixes + +* trigger release ([fe6038c](https://github.com/storacha/upload-service/commit/fe6038c2efca3a2cbdc3b8dc6221e36fc53bccc7)) + +## [1.1.2](https://github.com/storacha/upload-service/compare/upload-api-v1.1.1...upload-api-v1.1.2) (2024-11-08) + + +### Fixes + +* ensure idempotent ([9deef57](https://github.com/storacha/upload-service/commit/9deef577b8f79665e9df91d2c13e8747c86219f1)) + +## [1.1.1](https://github.com/storacha/upload-service/compare/upload-api-v1.1.0...upload-api-v1.1.1) (2024-11-07) + + +### Fixes + +* export Subscription type ([8c10e95](https://github.com/storacha/upload-service/commit/8c10e9506596748da288d55c63a53057f494ae8f)) + +## [1.1.0](https://github.com/storacha/upload-service/compare/upload-api-v1.0.4...upload-api-v1.1.0) (2024-11-07) + + +### Features + +* export test external service implementations ([2a2eb0c](https://github.com/storacha/upload-service/commit/2a2eb0c0280da85d514c8bca99fc8eea9fa0aa4a)) + +## [1.0.4](https://github.com/storacha/upload-service/compare/upload-api-v1.0.3...upload-api-v1.0.4) (2024-11-06) + + +### Fixes + +* invocation config does not extend ucan options ([cb473c5](https://github.com/storacha/upload-service/commit/cb473c5db2f11188a713861af99d7270f27958b7)) + +## [1.0.3](https://github.com/storacha/upload-service/compare/upload-api-v1.0.2...upload-api-v1.0.3) (2024-11-05) + + +### Fixes + +* export blob errors ([#33](https://github.com/storacha/upload-service/issues/33)) ([726ca23](https://github.com/storacha/upload-service/commit/726ca23bb2d9f891100456fb035b735280fbc185)) + +## [1.0.2](https://github.com/storacha/upload-service/compare/upload-api-v1.0.1...upload-api-v1.0.2) (2024-11-05) + + +### Fixes + +* re-export all blob types ([#30](https://github.com/storacha/upload-service/issues/30)) ([b10046b](https://github.com/storacha/upload-service/commit/b10046b6b8c6cace923081a3c0872522d98f723b)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/upload-api-v1.0.0...upload-api-v1.0.1) (2024-11-05) + + +### Fixes + +* record upload add cause ([#28](https://github.com/storacha/upload-service/issues/28)) ([6fc4311](https://github.com/storacha/upload-service/commit/6fc4311e6b0e660ab885028368992422174934b7)) + +## 1.0.0 (2024-11-05) + + +### Features + +* remove store protocol ([d59ec88](https://github.com/storacha/upload-service/commit/d59ec883ace9c3f084772f9520b6df81cc13b7af)) +* remove store protocol ([#13](https://github.com/storacha/upload-service/issues/13)) ([0028049](https://github.com/storacha/upload-service/commit/0028049f0bd3fcb816968687694c4611a5147148)) + + +### Other Changes + +* formatter ([f4f5f5a](https://github.com/storacha/upload-service/commit/f4f5f5accc0c80f3dfb1b6916d04df0e594c89af)) +* remove unused dependency ([e60c74d](https://github.com/storacha/upload-service/commit/e60c74dbbd2449a07a7e23671c82aa664d8b82b3)) + ## [18.1.0](https://github.com/storacha/w3up/compare/upload-api-v18.0.3...upload-api-v18.1.0) (2024-10-24) diff --git a/packages/upload-api/README.md b/packages/upload-api/README.md index a9bc56ff3..0712bd83d 100644 --- a/packages/upload-api/README.md +++ b/packages/upload-api/README.md @@ -1,27 +1,28 @@ -


web3.storage

-

The upload API for https://web3.storage

+

🐔
storacha.network

+

The upload API for https://storacha.network

-## About - -The `@web3-storage/upload-api` package provides an implementation of the w3up +The `@storacha/upload-api` package provides an implementation of the w3up UCAN invocation service. It provides a set of storage interfaces that can be implemented to run w3up on top of arbitrary data stores. ## Install Install the package using npm: + ```bash -npm install @web3-storage/upload-api +npm install @storacha/upload-api ``` ## Usage -Coming soon! +```js +import { ... } from '@storacha/upload-api' +``` ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/license.md) +Dual-licensed under [Apache 2.0 OR MIT](https://github.com/storacha/upload-service/blob/main/license.md) diff --git a/packages/upload-api/package.json b/packages/upload-api/package.json index 3f5267254..71851b232 100644 --- a/packages/upload-api/package.json +++ b/packages/upload-api/package.json @@ -1,13 +1,13 @@ { - "name": "@web3-storage/upload-api", - "description": "The upload api for web3.storage", - "version": "18.1.0", + "name": "@storacha/upload-api", + "description": "The upload api for storacha.network", + "version": "1.3.2", "type": "module", "main": "./src/lib.js", - "homepage": "https://web3.storage", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/upload-api" }, "files": [ @@ -57,9 +57,6 @@ "space": [ "dist/src/space.d.ts" ], - "store": [ - "dist/src/store.d.ts" - ], "subscription": [ "dist/src/subscription.d.ts" ], @@ -146,10 +143,6 @@ "types": "./dist/src/space.d.ts", "import": "./src/space.js" }, - "./store": { - "types": "./dist/src/store.d.ts", - "import": "./src/store.js" - }, "./subscription": { "types": "./dist/src/subscription.d.ts", "import": "./src/subscription.js" @@ -181,6 +174,10 @@ "./test/context": { "types": "./dist/test/helpers/context.d.ts", "import": "./test/helpers/context.js" + }, + "./test/external-service": { + "types": "./dist/test/external-service/index.d.ts", + "import": "./test/external-service/index.js" } }, "scripts": { @@ -193,38 +190,38 @@ "test-watch": "pnpm build && mocha --bail --timeout 10s --watch --parallel -n no-warnings -n experimental-vm-modules -n experimental-fetch --watch-files src,test" }, "dependencies": { + "@storacha/access": "workspace:^", + "@storacha/blob-index": "workspace:^", + "@storacha/capabilities": "workspace:^", + "@storacha/did-mailto": "workspace:^", + "@storacha/filecoin-api": "workspace:^", "@ucanto/client": "^9.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/principal": "^9.0.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/principal": "^9.0.2", "@ucanto/server": "^10.0.0", "@ucanto/transport": "^9.1.1", - "@ucanto/validator": "^9.0.2", - "@web3-storage/access": "workspace:^", - "@web3-storage/blob-index": "workspace:^", - "@web3-storage/capabilities": "workspace:^", - "@web3-storage/content-claims": "^5.1.0", - "@web3-storage/did-mailto": "workspace:^", - "@web3-storage/filecoin-api": "workspace:^", - "multiformats": "^12.1.2", + "@ucanto/validator": "^9.0.3", + "@web3-storage/content-claims": "^5.1.3", + "@web3-storage/upload-api": "^19.0.0", + "multiformats": "^13.3.1", "uint8arrays": "^5.0.3" }, "devDependencies": { "@ipld/car": "^5.1.1", - "@ipld/dag-ucan": "^3.4.0", + "@ipld/dag-ucan": "^3.4.5", + "@storacha/blob-index": "workspace:^", + "@storacha/eslint-config": "workspace:^", "@storacha/one-webcrypto": "^1.0.1", "@types/mocha": "^10.0.1", - "@ucanto/core": "^10.0.1", + "@ucanto/core": "^10.2.1", "@web-std/blob": "^3.0.5", - "@web3-storage/blob-index": "workspace:^", - "@web3-storage/eslint-config-w3up": "workspace:^", - "@web3-storage/sigv4": "^1.0.2", "is-subset": "^0.1.1", "mocha": "^10.2.0", "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -252,7 +249,7 @@ "ignores": [ "dist", "@types/*", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] }, "engines": { diff --git a/packages/upload-api/src/access/authorize.js b/packages/upload-api/src/access/authorize.js index a0417d413..66ff1f4d5 100644 --- a/packages/upload-api/src/access/authorize.js +++ b/packages/upload-api/src/access/authorize.js @@ -1,8 +1,8 @@ import * as Server from '@ucanto/server' import * as API from '../types.js' -import * as Access from '@web3-storage/capabilities/access' -import * as DidMailto from '@web3-storage/did-mailto' -import { delegationToString } from '@web3-storage/access/encoding' +import * as Access from '@storacha/capabilities/access' +import * as DidMailto from '@storacha/did-mailto' +import { delegationToString } from '@storacha/access/encoding' import { mailtoDidToDomain, mailtoDidToEmail } from '../utils/did-mailto.js' import { ensureRateLimitAbove } from '../utils/rate-limits.js' @@ -22,7 +22,7 @@ export const provide = (ctx) => */ export const authorize = async ({ capability, invocation }, ctx) => { const accountMailtoDID = - /** @type {import('@web3-storage/did-mailto/types').DidMailto} */ ( + /** @type {import('@storacha/did-mailto/types').DidMailto} */ ( capability.nb.iss ) const rateLimitResult = await ensureRateLimitAbove( diff --git a/packages/upload-api/src/access/claim.js b/packages/upload-api/src/access/claim.js index 6f5e2d513..8acd0c619 100644 --- a/packages/upload-api/src/access/claim.js +++ b/packages/upload-api/src/access/claim.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Access from '@web3-storage/capabilities/access' +import * as Access from '@storacha/capabilities/access' import * as UCAN from '@ipld/dag-ucan' import * as API from '../types.js' import * as delegationsResponse from '../utils/delegations-response.js' @@ -13,6 +13,7 @@ export const provide = (ctx) => /** * Checks if the given Principal is an Account. + * * @param {API.Principal} principal * @returns {principal is API.Principal>} */ @@ -20,6 +21,7 @@ const isAccount = (principal) => principal.did().startsWith('did:mailto:') /** * Returns true when the delegation has a `ucan:*` capability. + * * @param {API.Delegation} delegation * @returns boolean */ diff --git a/packages/upload-api/src/access/confirm.js b/packages/upload-api/src/access/confirm.js index 717f08ef8..4e7b4480a 100644 --- a/packages/upload-api/src/access/confirm.js +++ b/packages/upload-api/src/access/confirm.js @@ -1,8 +1,8 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' import { Absentee, Verifier } from '@ucanto/principal' -import * as Access from '@web3-storage/capabilities/access' -import * as UCAN from '@web3-storage/capabilities/ucan' +import * as Access from '@storacha/capabilities/access' +import * as UCAN from '@storacha/capabilities/ucan' import * as delegationsResponse from '../utils/delegations-response.js' /** diff --git a/packages/upload-api/src/access/delegate.js b/packages/upload-api/src/access/delegate.js index 85c6d30d0..39942b5e8 100644 --- a/packages/upload-api/src/access/delegate.js +++ b/packages/upload-api/src/access/delegate.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Access from '@web3-storage/capabilities/access' +import * as Access from '@storacha/capabilities/access' import * as API from '../types.js' import * as Allocator from '../space-allocate.js' diff --git a/packages/upload-api/src/admin.js b/packages/upload-api/src/admin.js index d43255d00..1b1b5c27e 100644 --- a/packages/upload-api/src/admin.js +++ b/packages/upload-api/src/admin.js @@ -1,15 +1,10 @@ import * as Types from './types.js' -import * as StoreInspect from './admin/store/inspect.js' import * as UploadInspect from './admin/upload/inspect.js' /** * @param {Types.AdminServiceContext} context */ export const createService = (context) => ({ - store: { - inspect: StoreInspect.provide(context), - }, - upload: { inspect: UploadInspect.provide(context), }, diff --git a/packages/upload-api/src/admin/store/inspect.js b/packages/upload-api/src/admin/store/inspect.js deleted file mode 100644 index 1ab7fa757..000000000 --- a/packages/upload-api/src/admin/store/inspect.js +++ /dev/null @@ -1,43 +0,0 @@ -import * as API from '../../types.js' -import * as Provider from '@ucanto/server' -import { Admin } from '@web3-storage/capabilities' - -/** - * @param {API.AdminServiceContext} context - */ -export const provide = (context) => - Provider.provide(Admin.store.inspect, (input) => inspect(input, context)) - -/** - * @param {API.Input} input - * @param {API.AdminServiceContext} context - * @returns {Promise} - */ -const inspect = async ({ capability }, context) => { - /** - * Ensure that resource is the service DID, which implies it's either - * invoked by service itself or an authorized delegate (like admin). - * In other words no user will be able to invoke this unless service - * explicitly delegated capability to them to do so. - */ - if (capability.with !== context.signer.did()) { - return { error: new UnknownProvider(capability.with) } - } - - return await context.storeTable.inspect(capability.nb.link) -} - -class UnknownProvider extends Provider.Failure { - /** - * @param {API.DID} did - */ - constructor(did) { - super() - this.did = did - this.name = /** @type {const} */ ('UnknownProvider') - } - - describe() { - return `Provider ${this.did} not found` - } -} diff --git a/packages/upload-api/src/admin/upload/inspect.js b/packages/upload-api/src/admin/upload/inspect.js index e7c49d1e2..e8a2dbda1 100644 --- a/packages/upload-api/src/admin/upload/inspect.js +++ b/packages/upload-api/src/admin/upload/inspect.js @@ -1,6 +1,6 @@ import * as API from '../../types.js' import * as Provider from '@ucanto/server' -import { Admin } from '@web3-storage/capabilities' +import { Admin } from '@storacha/capabilities' /** * @param {API.AdminServiceContext} context diff --git a/packages/upload-api/src/blob.js b/packages/upload-api/src/blob.js index 7df55c5da..88c0c7235 100644 --- a/packages/upload-api/src/blob.js +++ b/packages/upload-api/src/blob.js @@ -4,7 +4,13 @@ import { blobRemoveProvider } from './blob/remove.js' import { blobGetProvider } from './blob/get.js' import * as API from './types.js' -export { BlobNotFound } from './blob/lib.js' +export { + BlobNotFound, + EntryExists, + EntryNotFound, + BlobSizeLimitExceededError, + AllocatedMemoryNotWrittenError, +} from './blob/lib.js' /** * @param {API.BlobServiceContext} context diff --git a/packages/upload-api/src/blob/accept.js b/packages/upload-api/src/blob/accept.js index 94bdd3f5f..fde33d0bb 100644 --- a/packages/upload-api/src/blob/accept.js +++ b/packages/upload-api/src/blob/accept.js @@ -1,69 +1,12 @@ -import * as Server from '@ucanto/server' +import * as Blob from '@storacha/capabilities/blob' +import * as W3sBlob from '@storacha/capabilities/web3.storage/blob' +import { Message, Receipt, Invocation } from '@ucanto/core' +import * as Transport from '@ucanto/transport/car' +import * as API from '../types.js' +import * as HTTP from '@storacha/capabilities/http' import * as DID from '@ipld/dag-ucan/did' -import * as W3sBlob from '@web3-storage/capabilities/web3.storage/blob' -import { Assert } from '@web3-storage/content-claims/capability' -import { Invocation } from '@ucanto/core' import * as Digest from 'multiformats/hashes/digest' -import * as API from '../types.js' -import { - AllocatedMemoryHadNotBeenWrittenTo, - UnsupportedCapability, -} from './lib.js' -import * as HTTP from '@web3-storage/capabilities/http' - -/** - * @param {API.W3ServiceContext} context - * @returns {API.ServiceMethod} - */ -export function blobAcceptProvider(context) { - return Server.provideAdvanced({ - capability: W3sBlob.accept, - handler: async ({ capability }) => { - // Only service principal can perform an allocation - if (capability.with !== context.id.did()) { - return { - error: new UnsupportedCapability({ capability }), - } - } - - const { blob, space } = capability.nb - const digest = Digest.decode(blob.digest) - // If blob is not stored, we must fail - const hasBlob = await context.blobsStorage.has(digest) - if (hasBlob.error) { - return hasBlob - } else if (!hasBlob.ok) { - return { - error: new AllocatedMemoryHadNotBeenWrittenTo(), - } - } - - const createUrl = await context.blobsStorage.createDownloadUrl(digest) - if (createUrl.error) { - return createUrl - } - - const locationClaim = await Assert.location.delegate({ - issuer: context.id, - audience: DID.parse(space), - with: context.id.toDIDKey(), - nb: { - content: { digest: digest.bytes }, - location: [createUrl.ok], - }, - expiration: Infinity, - }) - - // Create result object - /** @type {API.OkBuilder} */ - const result = Server.ok({ - site: locationClaim.cid, - }) - - return result.fork(locationClaim) - }, - }) -} +import { AgentMessage } from '../lib.js' /** * Polls `blob/accept` task whenever we receive a receipt. It may error if passed @@ -72,7 +15,7 @@ export function blobAcceptProvider(context) { * * @param {API.ConcludeServiceContext} context * @param {API.Receipt} receipt - * @returns {Promise>} + * @returns {Promise>} */ export const poll = async (context, receipt) => { const ran = Invocation.isInvocation(receipt.ran) @@ -86,7 +29,7 @@ export const poll = async (context, receipt) => { } // Detect if this receipt is for an `http/put` invocation - const put = /** @type {?API.HTTPPut} */ ( + const put = /** @type {API.HTTPPut} */ ( ran.ok.capabilities.find(({ can }) => can === HTTP.put.can) ) @@ -108,32 +51,91 @@ export const poll = async (context, receipt) => { return result } + const provider = result.ok.audience const [allocate] = /** @type {[API.BlobAllocate]} */ (result.ok.capabilities) - // If this is a receipt for the http/put we will perform blob/accept. - const blobAccept = await W3sBlob.accept.invoke({ + const configure = await context.router.configureInvocation( + provider, + Blob.accept.create({ + with: provider.did(), + nb: { + blob: allocate.nb.blob, + space: allocate.nb.space, + _put: { + 'ucan/await': ['.out.ok', receipt.ran.link()], + }, + }, + }), + { + // ⚠️ We need invocation to be deterministic which is why we use exact + // same as it is on allocation which will guarantee that expiry is the + // same regardless when we received `http/put` receipt. + // + // ℹ️ This works around the fact that we index receipts by invocation link + // as opposed to task link which would not care about the expiration. + expiration: result.ok.expiration, + } + ) + if (configure.error) { + return configure + } + + const acceptReceipt = await configure.ok.invocation.execute( + configure.ok.connection + ) + + // Create receipt for legacy `web3.storage/blob/accept`. The old client + // `@web3-storage/w3up-client` will poll for a receipt for this task, so + // we create one whose result is simply the result of the actual `blob/accept` + // task. + // + // TODO: remove when all users migrate to `@storacha/client`. + const w3sAccept = W3sBlob.accept.invoke({ issuer: context.id, audience: context.id, with: context.id.did(), nb: { - blob: put.nb.body, - space: allocate.nb.space, - _put: { - 'ucan/await': ['.out.ok', receipt.ran.link()], - }, + blob: allocate.nb.blob, + space: /** @type {API.DIDKey} */ (DID.decode(allocate.nb.space).did()), + _put: { 'ucan/await': ['.out.ok', receipt.ran.link()] }, }, - // ⚠️ We need invocation to be deterministic which is why we use exact - // same as it is on allocation which will guarantee that expiry is the - // same regardless when we received `http/put` receipt. - // - // ℹ️ This works around the fact that we index receipts by invocation link - // as opposed to task link which would not care about the expiration. - expiration: result.ok.expiration, + }) + const w3sAcceptTask = await w3sAccept.delegate() + const w3sAcceptReceipt = await Receipt.issue({ + issuer: context.id, + ran: w3sAcceptTask.cid, + result: acceptReceipt.out, + fx: acceptReceipt.fx, }) - // We do not care about the result we just want receipt to be issued and - // stored. - await blobAccept.execute(context.getServiceConnection()) + // record the invocation and the receipt + const message = await Message.build({ + invocations: [configure.ok.invocation], + receipts: [acceptReceipt, w3sAcceptReceipt], + }) + const messageWrite = await context.agentStore.messages.write({ + source: await Transport.outbound.encode(message), + data: message, + index: [...AgentMessage.index(message)], + }) + if (messageWrite.error) { + return messageWrite + } + + const register = await context.registry.register({ + space: /** @type {API.SpaceDID} */ (DID.decode(allocate.nb.space).did()), + cause: allocate.nb.cause, + blob: { + digest: Digest.decode(allocate.nb.blob.digest), + size: allocate.nb.blob.size, + }, + }) + if (register.error) { + // it's ok if there's already a registration of this blob in this space + if (register.error.name !== 'EntryExists') { + return register + } + } return { ok: {} } } diff --git a/packages/upload-api/src/blob/add.js b/packages/upload-api/src/blob/add.js index 5729c051f..f37372c0c 100644 --- a/packages/upload-api/src/blob/add.js +++ b/packages/upload-api/src/blob/add.js @@ -1,13 +1,18 @@ import * as Server from '@ucanto/server' -import { Receipt } from '@ucanto/core' +import { Message, Receipt } from '@ucanto/core' +import * as Transport from '@ucanto/transport/car' import { ed25519 } from '@ucanto/principal' -import * as Blob from '@web3-storage/capabilities/blob' -import * as W3sBlob from '@web3-storage/capabilities/web3.storage/blob' -import * as HTTP from '@web3-storage/capabilities/http' +import * as Blob from '@storacha/capabilities/blob' +import * as SpaceBlob from '@storacha/capabilities/space/blob' +import * as W3sBlob from '@storacha/capabilities/web3.storage/blob' +import * as HTTP from '@storacha/capabilities/http' +import * as Digest from 'multiformats/hashes/digest' +import * as DID from '@ipld/dag-ucan/did' import * as API from '../types.js' - +import { allocate as spaceAllocate } from '../space-allocate.js' import { createConcludeInvocation } from '../ucan/conclude.js' import { AwaitError } from './lib.js' +import { AgentMessage } from '../lib.js' /** * Derives did:key principal from (blob) multihash that can be used to @@ -27,11 +32,11 @@ const conclude = (receipt, issuer, audience = issuer) => /** * @param {API.BlobServiceContext} context - * @returns {API.ServiceMethod} + * @returns {API.ServiceMethod} */ export function blobAddProvider(context) { return Server.provideAdvanced({ - capability: Blob.add, + capability: SpaceBlob.add, handler: async ({ capability, invocation }) => { const { with: space, nb } = capability const { blob } = nb @@ -42,33 +47,65 @@ export function blobAddProvider(context) { space, cause: invocation.link(), }) + if (allocation.error) { + return allocation + } + + const allocationW3s = await allocateW3s({ + context, + blob, + space, + cause: invocation.link(), + receipt: allocation.ok.receipt, + }) const delivery = await put({ blob, - allocation, + allocation: allocation.ok, }) const acceptance = await accept({ context, + provider: allocation.ok.provider, + blob, + space, + delivery: delivery, + }) + if (acceptance.error) { + return acceptance + } + + const acceptanceW3s = await acceptW3s({ + context, + provider: allocation.ok.provider, blob, space, - delivery, + delivery: delivery, + acceptance: acceptance.ok, }) - // Create a result describing the this invocation workflow + // Create a result describing this invocation workflow let result = Server.ok({ - /** @type {API.BlobAddSuccess['site']} */ + /** @type {API.SpaceBlobAddSuccess['site']} */ site: { - 'ucan/await': ['.out.ok.site', acceptance.task.link()], + 'ucan/await': ['.out.ok.site', acceptance.ok.task.link()], }, }) - .fork(allocation.task) + .fork(allocation.ok.task) + .fork(allocationW3s.task) .fork(delivery.task) - .fork(acceptance.task) + .fork(acceptance.ok.task) + .fork(acceptanceW3s.task) // As a temporary solution we fork all add effects that add inline // receipts so they can be delivered to the client. - const fx = [...allocation.fx, ...delivery.fx, ...acceptance.fx] + const fx = [ + ...allocation.ok.fx, + ...allocationW3s.fx, + ...delivery.fx, + ...acceptance.ok.fx, + ...acceptanceW3s.fx, + ] for (const task of fx) { result = result.fork(task) } @@ -89,21 +126,62 @@ export function blobAddProvider(context) { * @param {API.Link} allocate.cause */ async function allocate({ context, blob, space, cause }) { - // 1. Create web3.storage/blob/allocate invocation and task - const allocate = W3sBlob.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), + // First we check if space has storage provider associated. If it does not + // we return `InsufficientStorage` error as storage capacity is considered + // to be 0. + const provisioned = await spaceAllocate( + { capability: { with: space } }, + context + ) + if (provisioned.error) { + return provisioned + } + + // 1. Create blob/allocate invocation and task + const { router } = context + const digest = Digest.decode(blob.digest) + + const candidate = await router.selectStorageProvider(digest, blob.size) + if (candidate.error) { + return candidate + } + + const cap = Blob.allocate.create({ + with: candidate.ok.did(), nb: { - blob, - cause: cause, - space, + blob: { + digest: blob.digest, + size: blob.size, + }, + space: DID.parse(space), + cause, }, + }) + + const configure = await router.configureInvocation(candidate.ok, cap, { expiration: Infinity, }) - const task = await allocate.delegate() + if (configure.error) { + return configure + } - const receipt = await allocate.execute(context.getServiceConnection()) + const task = await configure.ok.invocation.delegate() + const receipt = await configure.ok.invocation.execute(configure.ok.connection) + + // record the invocation and the receipt, so we can retrieve it later when we + // get a http/put receipt in ucan/conclude + const message = await Message.build({ + invocations: [configure.ok.invocation], + receipts: [receipt], + }) + const messageWrite = await context.agentStore.messages.write({ + source: await Transport.outbound.encode(message), + data: message, + index: [...AgentMessage.index(message)], + }) + if (messageWrite.error) { + return messageWrite + } // 4. Create `blob/allocate` receipt as conclude invocation to inline as effect const concludeAllocate = createConcludeInvocation( @@ -112,10 +190,54 @@ async function allocate({ context, blob, space, cause }) { receipt ) - return { + return Server.ok({ + provider: candidate.ok, task, receipt, fx: [await concludeAllocate.delegate()], + }) +} + +/** + * Create an allocation task and receipt using the legacy + * `web3.storage/blob/allocate` capability. This enables backwards compatibility + * with `@web3-storage/w3up-client`. + * + * TODO: remove when all users migrate to `@storacha/client`. + * + * @param {object} allocate + * @param {API.BlobServiceContext} allocate.context + * @param {API.BlobModel} allocate.blob + * @param {API.DIDKey} allocate.space + * @param {API.Link} allocate.cause + * @param {API.Receipt} allocate.receipt + */ +async function allocateW3s({ context, blob, space, cause, receipt }) { + const w3sAllocate = W3sBlob.allocate.invoke({ + issuer: context.id, + audience: context.id, + with: context.id.did(), + nb: { blob, cause, space }, + expiration: Infinity, + }) + const w3sAllocateTask = await w3sAllocate.delegate() + + const w3sAllocateReceipt = await Receipt.issue({ + issuer: context.id, + ran: w3sAllocateTask.cid, + result: receipt.out, + }) + + const w3sAllocateConclude = createConcludeInvocation( + context.id, + context.id, + w3sAllocateReceipt + ) + + return { + task: w3sAllocateTask, + receipt: w3sAllocateReceipt, + fx: [await w3sAllocateConclude.delegate()], } } @@ -206,26 +328,32 @@ async function put({ blob, allocation }) { * * @param {object} input * @param {API.BlobServiceContext} input.context + * @param {API.Principal} input.provider * @param {API.BlobModel} input.blob * @param {API.DIDKey} input.space * @param {object} input.delivery * @param {API.Invocation} input.delivery.task * @param {API.Receipt|null} input.delivery.receipt */ -async function accept({ context, blob, space, delivery }) { - // 1. Create web3.storage/blob/accept invocation and task - const accept = W3sBlob.accept.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), +async function accept({ context, provider, blob, space, delivery }) { + // 1. Create blob/accept invocation and task + const cap = Blob.accept.create({ + with: provider.did(), nb: { blob, - space, + space: DID.parse(space), _put: { 'ucan/await': ['.out.ok', delivery.task.link()] }, }, + }) + + const configure = await context.router.configureInvocation(provider, cap, { expiration: Infinity, }) - const task = await accept.delegate() + if (configure.error) { + return configure + } + + const task = await configure.ok.invocation.delegate() let receipt = null @@ -245,12 +373,75 @@ async function accept({ context, blob, space, delivery }) { } // If put has already succeeded, we can execute `blob/accept` right away. else if (delivery.receipt?.out.ok) { - receipt = await accept.execute(context.getServiceConnection()) + receipt = await configure.ok.invocation.execute(configure.ok.connection) } - return { + return Server.ok({ task, receipt, fx: receipt ? [await conclude(receipt, context.id)] : [], + }) +} + +/** + * Create an accept task and receipt using the legacy + * `web3.storage/blob/accept` capability. This enables backwards compatibility + * with `@web3-storage/w3up-client`. + * + * TODO: remove when all users migrate to `@storacha/client`. + * + * @param {object} input + * @param {API.BlobServiceContext} input.context + * @param {API.Principal} input.provider + * @param {API.BlobModel} input.blob + * @param {API.DIDKey} input.space + * @param {object} input.delivery + * @param {API.Invocation} input.delivery.task + * @param {API.Receipt|null} input.delivery.receipt + * @param {object} input.acceptance + * @param {API.Receipt|null} input.acceptance.receipt + */ +async function acceptW3s({ context, blob, space, delivery, acceptance }) { + // 1. Create web3.storage/blob/accept invocation and task + const w3sAccept = W3sBlob.accept.invoke({ + issuer: context.id, + audience: context.id, + with: context.id.did(), + nb: { + blob, + space, + _put: { 'ucan/await': ['.out.ok', delivery.task.link()] }, + }, + }) + const w3sAcceptTask = await w3sAccept.delegate() + + let w3sAcceptReceipt = null + // If put has failed, we propagate the error to the `blob/accept` receipt. + if (delivery.receipt?.out.error) { + w3sAcceptReceipt = await Receipt.issue({ + issuer: context.id, + ran: w3sAcceptTask, + result: { + error: new AwaitError({ + cause: delivery.receipt.out.error, + at: '.out.ok', + reference: delivery.task.link(), + }), + }, + }) + } + // If `blob/accept` receipt is present, we issue a receipt for + // `web3.storage/blob/accept`. + else if (acceptance.receipt) { + w3sAcceptReceipt = await Receipt.issue({ + issuer: context.id, + ran: w3sAcceptTask, + result: acceptance.receipt.out, + }) + } + + return { + task: w3sAcceptTask, + fx: w3sAcceptReceipt ? [await conclude(w3sAcceptReceipt, context.id)] : [], } } diff --git a/packages/upload-api/src/blob/allocate.js b/packages/upload-api/src/blob/allocate.js deleted file mode 100644 index 5898aadb0..000000000 --- a/packages/upload-api/src/blob/allocate.js +++ /dev/null @@ -1,131 +0,0 @@ -import * as Server from '@ucanto/server' -import * as W3sBlob from '@web3-storage/capabilities/web3.storage/blob' -import * as Digest from 'multiformats/hashes/digest' -import * as API from '../types.js' -import { - BlobSizeOutsideOfSupportedRange, - UnsupportedCapability, -} from './lib.js' - -/** - * @param {API.BlobServiceContext} context - * @returns {API.ServiceMethod} - */ -export const blobAllocateProvider = (context) => - Server.provide(W3sBlob.allocate, (input) => allocate(context, input)) - -/** - * @param {API.BlobServiceContext} context - * @param {API.ProviderInput} input - */ -export const allocate = async (context, { capability }) => { - // Only service principal can perform an allocation - if (capability.with !== context.id.did()) { - return { - error: new UnsupportedCapability({ capability }), - } - } - - const { blob, cause, space } = capability.nb - const digest = Digest.decode(blob.digest) - let { size } = blob - - // We check if space has storage provider associated. If it does not - // we return `InsufficientStorage` error as storage capacity is considered - // to be 0. - const result = await context.provisionsStorage.hasStorageProvider(space) - if (result.error) { - return result - } - - if (!result.ok) { - return { - /** @type {API.AllocationError} */ - error: { - name: 'InsufficientStorage', - message: `${space} has no storage provider`, - }, - } - } - - // Verify blob is within the max upload size. - if (capability.nb.blob.size > context.maxUploadSize) { - // While blob may exceed current maxUploadSize limit it could be that limit - // was higher in the past and user had this blob uploaded already in which - // case we should not error. - const exists = await context.allocationsStorage.exists(space, digest) - if (exists.ok) { - return { ok: { size: 0 } } - } else { - return { - error: new BlobSizeOutsideOfSupportedRange( - capability.nb.blob.size, - context.maxUploadSize - ), - } - } - } - - // Allocate memory space for the blob. If memory for this blob is - // already allocated, this allocates 0 bytes. - const allocationInsert = await context.allocationsStorage.insert({ - space, - blob, - cause, - }) - - if (allocationInsert.error) { - // if the insert failed with conflict then this item has already been - // added to the space and there is no allocation change. - // If record exists but is expired, it can be re-written - if (allocationInsert.error.name === 'RecordKeyConflict') { - size = 0 - } else { - return { - error: allocationInsert.error, - } - } - } - - // Check if we already have blob stored - // TODO: this may depend on the region we want to allocate and will need - // changes in the future. - const hasBlobStore = await context.blobsStorage.has(digest) - if (hasBlobStore.error) { - return hasBlobStore - } - - // If blob is stored, we can just allocate it to the space with the allocated size - // TODO: this code path MAY lead to await failures - awaited http/put and blob/accept tasks - // are supposed to fail if path does not exists. - if (hasBlobStore.ok) { - return { - ok: { size }, - } - } - - // Get presigned URL for the write target - const expiresIn = 60 * 60 * 24 // 1 day - const expiresAt = new Date(Date.now() + expiresIn).toISOString() - const createUploadUrl = await context.blobsStorage.createUploadUrl( - digest, - blob.size, - expiresIn - ) - if (createUploadUrl.error) { - return createUploadUrl - } - - const address = { - url: createUploadUrl.ok.url.toString(), - headers: createUploadUrl.ok.headers, - expiresAt, - } - - return { - ok: { - size, - address, - }, - } -} diff --git a/packages/upload-api/src/blob/get.js b/packages/upload-api/src/blob/get.js index 2176a4b7f..72d70a055 100644 --- a/packages/upload-api/src/blob/get.js +++ b/packages/upload-api/src/blob/get.js @@ -1,21 +1,32 @@ import * as Server from '@ucanto/server' -import * as Blob from '@web3-storage/capabilities/blob' +import * as SpaceBlob from '@storacha/capabilities/space/blob' import * as Digest from 'multiformats/hashes/digest' import * as API from '../types.js' import { BlobNotFound } from './lib.js' /** * @param {API.BlobServiceContext} context - * @returns {API.ServiceMethod} + * @returns {API.ServiceMethod} */ export function blobGetProvider(context) { - return Server.provide(Blob.get, async ({ capability }) => { + return Server.provide(SpaceBlob.get, async ({ capability }) => { const digest = Digest.decode(capability.nb.digest) const space = Server.DID.parse(capability.with).did() - const res = await context.allocationsStorage.get(space, digest) - if (res.error && res.error.name === 'RecordNotFound') { - return Server.error(new BlobNotFound(digest)) + const res = await context.registry.find(space, digest) + if (res.error) { + if (res.error.name === 'EntryNotFound') { + return Server.error(new BlobNotFound(digest)) + } + return res } - return res + + return Server.ok({ + blob: { + digest: res.ok.blob.digest.bytes, + size: res.ok.blob.size, + }, + cause: res.ok.cause, + insertedAt: res.ok.insertedAt.toISOString(), + }) }) } diff --git a/packages/upload-api/src/blob/lib.js b/packages/upload-api/src/blob/lib.js index ca4393442..902a80815 100644 --- a/packages/upload-api/src/blob/lib.js +++ b/packages/upload-api/src/blob/lib.js @@ -2,48 +2,6 @@ import { Failure } from '@ucanto/server' import { base58btc } from 'multiformats/bases/base58' import * as API from '../types.js' -export const AllocatedMemoryHadNotBeenWrittenToName = - 'AllocatedMemoryHadNotBeenWrittenTo' -export class AllocatedMemoryHadNotBeenWrittenTo extends Failure { - get name() { - return AllocatedMemoryHadNotBeenWrittenToName - } - - describe() { - return `Blob not found` - } -} - -export const BlobSizeOutsideOfSupportedRangeName = - 'BlobSizeOutsideOfSupportedRange' -export class BlobSizeOutsideOfSupportedRange extends Failure { - /** - * @param {number} blobSize - * @param {number} maxUploadSize - */ - constructor(blobSize, maxUploadSize) { - super() - this.blobSize = blobSize - this.maxUploadSize = maxUploadSize - } - - get name() { - return BlobSizeOutsideOfSupportedRangeName - } - - describe() { - return `Blob size ${this.blobSize} exceeded maximum size limit: ${this.maxUploadSize}, consider splitting it into blobs that fit limit.` - } - - toJSON() { - return { - ...super.toJSON(), - maxUploadSize: this.maxUploadSize, - blobSize: this.blobSize, - } - } -} - export const AwaitErrorName = 'AwaitError' /** @@ -99,20 +57,60 @@ export class BlobNotFound extends Failure { } } -export class UnsupportedCapability extends Failure { - /** - * @param {object} source - * @param {API.Capability} source.capability - */ - constructor({ capability: { with: subject, can } }) { - super() +export class EntryNotFound extends Failure { + static name = /** @type {const} */ ('EntryNotFound') + + get reason() { + return this.message + } + + get name() { + return EntryNotFound.name + } +} + +export class EntryExists extends Failure { + static name = /** @type {const} */ ('EntryExists') + + get reason() { + return this.message + } + + get name() { + return EntryExists.name + } +} - this.capability = { with: subject, can } +export class AllocatedMemoryNotWrittenError extends Failure { + static name = /** @type {const} */ ('AllocatedMemoryHadNotBeenWrittenTo') + + get name() { + return AllocatedMemoryNotWrittenError.name } + + describe() { + return 'Blob not found' + } +} + +export class BlobSizeLimitExceededError extends Failure { + static name = /** @type {const} */ ('BlobSizeOutsideOfSupportedRange') + get name() { - return /** @type {const} */ ('UnsupportedCapability') + return BlobSizeLimitExceededError.name } + + /** + * @param {number} size + * @param {number} max + */ + constructor(size, max) { + super() + this.size = size + this.max = max + } + describe() { - return `${this.capability.with} does not have a "${this.capability.can}" capability provider` + return `Blob of ${this.size} bytes, exceeds size limit of ${this.max} bytes` } } diff --git a/packages/upload-api/src/blob/list.js b/packages/upload-api/src/blob/list.js index 694d3d3d0..5ebaf48de 100644 --- a/packages/upload-api/src/blob/list.js +++ b/packages/upload-api/src/blob/list.js @@ -1,15 +1,29 @@ import * as Server from '@ucanto/server' -import * as Blob from '@web3-storage/capabilities/blob' +import * as SpaceBlob from '@storacha/capabilities/space/blob' import * as API from '../types.js' /** * @param {API.BlobServiceContext} context - * @returns {API.ServiceMethod} + * @returns {API.ServiceMethod} */ export function blobListProvider(context) { - return Server.provide(Blob.list, async ({ capability }) => { + return Server.provide(SpaceBlob.list, async ({ capability }) => { const space = capability.with const { cursor, size } = capability.nb - return await context.allocationsStorage.list(space, { size, cursor }) + const result = await context.registry.entries(space, { size, cursor }) + if (result.error) { + return result + } + return Server.ok({ + ...result.ok, + results: result.ok.results.map((r) => ({ + blob: { + digest: r.blob.digest.bytes, + size: r.blob.size, + }, + cause: r.cause, + insertedAt: r.insertedAt.toISOString(), + })), + }) }) } diff --git a/packages/upload-api/src/blob/remove.js b/packages/upload-api/src/blob/remove.js index cd157326f..1cf00085d 100644 --- a/packages/upload-api/src/blob/remove.js +++ b/packages/upload-api/src/blob/remove.js @@ -1,28 +1,34 @@ import * as Server from '@ucanto/server' -import * as Blob from '@web3-storage/capabilities/blob' +import * as SpaceBlob from '@storacha/capabilities/space/blob' import * as Digest from 'multiformats/hashes/digest' import * as API from '../types.js' -import { RecordNotFoundErrorName } from '../errors.js' - /** * @param {API.BlobServiceContext} context - * @returns {API.ServiceMethod} + * @returns {API.ServiceMethod} */ export function blobRemoveProvider(context) { - return Server.provide(Blob.remove, async ({ capability }) => { + return Server.provide(SpaceBlob.remove, async ({ capability, invocation }) => { const space = capability.with const digest = Digest.decode(capability.nb.digest) - const res = await context.allocationsStorage.remove(space, digest) - if (res.error && res.error.name === RecordNotFoundErrorName) { - return { - ok: { - size: 0, - }, + const exists = await context.registry.find(space, digest) + if (exists.error) { + if (exists.error.name === 'EntryNotFound') { + return Server.ok({ size: 0 }) + } + return exists + } + + const dereg = await context.registry.deregister({space, digest, cause: invocation.link()}) + if (dereg.error) { + // unlikely as we just found it...but possible I guess + if (dereg.error.name === 'EntryNotFound') { + return Server.ok({ size: 0 }) } + return dereg } - return res + return Server.ok({ size: exists.ok?.blob.size }) }) } diff --git a/packages/upload-api/src/console.js b/packages/upload-api/src/console.js index 4bf948789..85e16a48d 100644 --- a/packages/upload-api/src/console.js +++ b/packages/upload-api/src/console.js @@ -1,4 +1,4 @@ -import { Console } from '@web3-storage/capabilities' +import { Console } from '@storacha/capabilities' import * as Provider from '@ucanto/server' import * as API from './types.js' diff --git a/packages/upload-api/src/consumer/get.js b/packages/upload-api/src/consumer/get.js index ed060366e..30fa6dbcc 100644 --- a/packages/upload-api/src/consumer/get.js +++ b/packages/upload-api/src/consumer/get.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Consumer } from '@web3-storage/capabilities' +import { Consumer } from '@storacha/capabilities' /** * @param {API.ConsumerServiceContext} context diff --git a/packages/upload-api/src/consumer/has.js b/packages/upload-api/src/consumer/has.js index 3bdc70043..1ce37f0bb 100644 --- a/packages/upload-api/src/consumer/has.js +++ b/packages/upload-api/src/consumer/has.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Consumer } from '@web3-storage/capabilities' +import { Consumer } from '@storacha/capabilities' /** * @param {API.ConsumerServiceContext} context diff --git a/packages/upload-api/src/customer/get.js b/packages/upload-api/src/customer/get.js index 89dbc93c6..1f42cc150 100644 --- a/packages/upload-api/src/customer/get.js +++ b/packages/upload-api/src/customer/get.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Customer } from '@web3-storage/capabilities' +import { Customer } from '@storacha/capabilities' /** * @param {API.CustomerServiceContext} context diff --git a/packages/upload-api/src/index/add.js b/packages/upload-api/src/index/add.js index 8ae702ee4..5bbf4e8e3 100644 --- a/packages/upload-api/src/index/add.js +++ b/packages/upload-api/src/index/add.js @@ -1,29 +1,29 @@ import * as Server from '@ucanto/server' import { ok, error } from '@ucanto/server' -import * as Index from '@web3-storage/capabilities/index' -import { ShardedDAGIndex } from '@web3-storage/blob-index' +import * as SpaceIndex from '@storacha/capabilities/space/index' +import { ShardedDAGIndex } from '@storacha/blob-index' import { Assert } from '@web3-storage/content-claims/capability' import { concat } from 'uint8arrays' import * as API from '../types.js' /** * @param {API.IndexServiceContext} context - * @returns {API.ServiceMethod} + * @returns {API.ServiceMethod} */ export const provide = (context) => - Server.provide(Index.add, (input) => add(input, context)) + Server.provide(SpaceIndex.add, (input) => add(input, context)) /** - * @param {API.Input} input + * @param {API.Input} input * @param {API.IndexServiceContext} context - * @returns {Promise>} + * @returns {Promise>} */ const add = async ({ capability }, context) => { const space = capability.with const idxLink = capability.nb.index // ensure the index was stored in the agent's space - const idxAllocRes = await assertAllocated( + const idxAllocRes = await assertRegistered( context, space, idxLink.multihash, @@ -59,7 +59,9 @@ const add = async ({ capability }, context) => { // ensure indexed shards are allocated in the agent's space const shardDigests = [...idxRes.ok.shards.keys()] const shardAllocRes = await Promise.all( - shardDigests.map((s) => assertAllocated(context, space, s, 'ShardNotFound')) + shardDigests.map((s) => + assertRegistered(context, space, s, 'ShardNotFound') + ) ) for (const res of shardAllocRes) { if (res.error) return res @@ -67,33 +69,34 @@ const add = async ({ capability }, context) => { // TODO: randomly validate slices in the index correspond to slices in the blob - const publishRes = await Promise.all([ - // publish the index data to IPNI - context.ipniService.publish(idxRes.ok), - // publish a content claim for the index - publishIndexClaim(context, { content: idxRes.ok.content, index: idxLink }), - ]) - for (const res of publishRes) { - if (res.error) return res + const publishRes = await publishIndexClaim(context, { + content: idxRes.ok.content, + index: idxLink, + }) + if (publishRes.error) { + return publishRes } return ok({}) } /** - * @param {{ allocationsStorage: import('../types.js').AllocationsStorage }} context + * @param {{ registry: import('../types/blob.js').Registry }} context * @param {API.SpaceDID} space * @param {import('multiformats').MultihashDigest} digest * @param {'IndexNotFound'|'ShardNotFound'|'SliceNotFound'} errorName * @returns {Promise>} */ -const assertAllocated = async (context, space, digest, errorName) => { - const result = await context.allocationsStorage.exists(space, digest) - if (result.error) return result - if (!result.ok) - return error( - /** @type {API.IndexNotFound|API.ShardNotFound|API.SliceNotFound} */ - ({ name: errorName, digest: digest.bytes }) - ) +const assertRegistered = async (context, space, digest, errorName) => { + const result = await context.registry.find(space, digest) + if (result.error) { + if (result.error.name === 'EntryNotFound') { + return error( + /** @type {API.IndexNotFound|API.ShardNotFound|API.SliceNotFound} */ + ({ name: errorName, digest: digest.bytes }) + ) + } + return result + } return ok({}) } diff --git a/packages/upload-api/src/lib.js b/packages/upload-api/src/lib.js index 1d866b6ab..204e239f6 100644 --- a/packages/upload-api/src/lib.js +++ b/packages/upload-api/src/lib.js @@ -6,7 +6,6 @@ import * as Types from './types.js' import * as Legacy from '@ucanto/transport/legacy' import * as CAR from '@ucanto/transport/car' import { create as createRevocationChecker } from './utils/revocation.js' -import { createService as createStoreService } from './store.js' import { createService as createUploadService } from './upload.js' import { createService as createConsoleService } from './console.js' import { createService as createAccessService } from './access.js' @@ -18,10 +17,11 @@ import { createService as createSubscriptionService } from './subscription.js' import { createService as createAdminService } from './admin.js' import { createService as createRateLimitService } from './rate-limit.js' import { createService as createUcanService } from './ucan.js' -import { createService as createW3sService } from './service.js' import { createService as createPlanService } from './plan.js' import { createService as createUsageService } from './usage.js' -import { createService as createFilecoinService } from '@web3-storage/filecoin-api/storefront/service' +import { createService as createFilecoinService } from '@storacha/filecoin-api/storefront/service' +import { createService as createLegacyAdminService } from '@web3-storage/upload-api/admin' +import { createService as createLegacyStoreService } from '@web3-storage/upload-api/store' import * as AgentMessage from './utils/agent-message.js' export * from './types.js' @@ -147,8 +147,8 @@ export const execute = async (agent, input) => { * a receipt it will return receipt without running invocation. * * @template {Record} S - * @param {Types.Invocation} invocation * @param {Agent} agent + * @param {Types.Invocation} invocation */ export const run = async (agent, invocation) => { const cached = await agent.context.agentStore.receipts.get(invocation.link()) @@ -180,17 +180,22 @@ export const createService = (context) => ({ customer: createCustomerService(context), provider: createProviderService(context), 'rate-limit': createRateLimitService(context), - admin: createAdminService(context), + admin: { + ...createAdminService(context), + // @ts-expect-error `uploadTable` items now have a `cause` field. This does + // not matter since `admin/store/inspect` handler does not use this table. + store: createLegacyAdminService(context).store + }, space: createSpaceService(context), - store: createStoreService(context), subscription: createSubscriptionService(context), upload: createUploadService(context), ucan: createUcanService(context), plan: createPlanService(context), - ['web3.storage']: createW3sService(context), // storefront of filecoin pipeline filecoin: createFilecoinService(context).filecoin, usage: createUsageService(context), + // legacy + store: createLegacyStoreService(context), }) /** diff --git a/packages/upload-api/src/plan/create-admin-session.js b/packages/upload-api/src/plan/create-admin-session.js index 7947c6841..9152afec3 100644 --- a/packages/upload-api/src/plan/create-admin-session.js +++ b/packages/upload-api/src/plan/create-admin-session.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Plan } from '@web3-storage/capabilities' +import { Plan } from '@storacha/capabilities' /** * @param {API.PlanServiceContext} context diff --git a/packages/upload-api/src/plan/get.js b/packages/upload-api/src/plan/get.js index d146aa55f..4b8836662 100644 --- a/packages/upload-api/src/plan/get.js +++ b/packages/upload-api/src/plan/get.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Plan } from '@web3-storage/capabilities' +import { Plan } from '@storacha/capabilities' /** * @param {API.PlanServiceContext} context diff --git a/packages/upload-api/src/plan/set.js b/packages/upload-api/src/plan/set.js index dc7146cb3..f34ac4b62 100644 --- a/packages/upload-api/src/plan/set.js +++ b/packages/upload-api/src/plan/set.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Plan } from '@web3-storage/capabilities' +import { Plan } from '@storacha/capabilities' /** * @param {API.PlanServiceContext} context diff --git a/packages/upload-api/src/provider-add.js b/packages/upload-api/src/provider-add.js index 7c12e875a..693f31a14 100644 --- a/packages/upload-api/src/provider-add.js +++ b/packages/upload-api/src/provider-add.js @@ -1,6 +1,6 @@ import * as API from './types.js' import * as Server from '@ucanto/server' -import { Provider } from '@web3-storage/capabilities' +import { Provider } from '@storacha/capabilities' import * as validator from '@ucanto/validator' import { mailtoDidToDomain, mailtoDidToEmail } from './utils/did-mailto.js' import { ensureRateLimitAbove } from './utils/rate-limits.js' @@ -37,9 +37,7 @@ export const add = async ( } } const accountMailtoDID = - /** @type {import('@web3-storage/did-mailto/types').DidMailto} */ ( - accountDID - ) + /** @type {import('@storacha/did-mailto/types').DidMailto} */ (accountDID) const rateLimitResult = await ensureRateLimitAbove( rateLimits, [mailtoDidToDomain(accountMailtoDID), mailtoDidToEmail(accountMailtoDID)], diff --git a/packages/upload-api/src/rate-limit/add.js b/packages/upload-api/src/rate-limit/add.js index 4cf6906bd..f6b3f9a16 100644 --- a/packages/upload-api/src/rate-limit/add.js +++ b/packages/upload-api/src/rate-limit/add.js @@ -1,6 +1,6 @@ import * as Server from '@ucanto/server' import * as API from '../types.js' -import * as RateLimit from '@web3-storage/capabilities/rate-limit' +import * as RateLimit from '@storacha/capabilities/rate-limit' /** * @param {API.RateLimitServiceContext} ctx diff --git a/packages/upload-api/src/rate-limit/list.js b/packages/upload-api/src/rate-limit/list.js index 8e770160c..ef71d441e 100644 --- a/packages/upload-api/src/rate-limit/list.js +++ b/packages/upload-api/src/rate-limit/list.js @@ -1,6 +1,6 @@ import * as Server from '@ucanto/server' import * as API from '../types.js' -import * as RateLimit from '@web3-storage/capabilities/rate-limit' +import * as RateLimit from '@storacha/capabilities/rate-limit' /** * @param {API.RateLimitServiceContext} ctx diff --git a/packages/upload-api/src/rate-limit/remove.js b/packages/upload-api/src/rate-limit/remove.js index 3fe4caead..e6d489cc7 100644 --- a/packages/upload-api/src/rate-limit/remove.js +++ b/packages/upload-api/src/rate-limit/remove.js @@ -1,6 +1,6 @@ import * as Server from '@ucanto/server' import * as API from '../types.js' -import * as RateLimit from '@web3-storage/capabilities/rate-limit' +import * as RateLimit from '@storacha/capabilities/rate-limit' /** * @param {API.RateLimitServiceContext} ctx diff --git a/packages/upload-api/src/service.js b/packages/upload-api/src/service.js deleted file mode 100644 index 50c383838..000000000 --- a/packages/upload-api/src/service.js +++ /dev/null @@ -1,15 +0,0 @@ -import { blobAllocateProvider } from './blob/allocate.js' -import { blobAcceptProvider } from './blob/accept.js' -import * as API from './types.js' - -/** - * @param {API.BlobServiceContext} context - */ -export function createService(context) { - return { - blob: { - allocate: blobAllocateProvider(context), - accept: blobAcceptProvider(context), - }, - } -} diff --git a/packages/upload-api/src/space-allocate.js b/packages/upload-api/src/space-allocate.js index ba01201cc..00d7d9fdb 100644 --- a/packages/upload-api/src/space-allocate.js +++ b/packages/upload-api/src/space-allocate.js @@ -1,7 +1,7 @@ import * as API from './types.js' import * as Server from '@ucanto/server' import * as Ucanto from '@ucanto/interface' -import * as Space from '@web3-storage/capabilities/space' +import * as Space from '@storacha/capabilities/space' import { ensureRateLimitAbove } from './utils/rate-limits.js' /** diff --git a/packages/upload-api/src/space.js b/packages/upload-api/src/space.js index a4a030a36..26d4fee7c 100644 --- a/packages/upload-api/src/space.js +++ b/packages/upload-api/src/space.js @@ -1,16 +1,18 @@ -import { Space } from '@web3-storage/capabilities' +import { Space } from '@storacha/capabilities' import * as Provider from '@ucanto/server' import * as API from './types.js' import { info } from './space/info.js' +import { provide as provideRecordEgress } from './space/record.js' import { createService as createBlobService } from './blob.js' import { createService as createIndexService } from './index.js' /** - * @param {API.SpaceServiceContext & API.BlobServiceContext & API.IndexServiceContext} ctx + * @param {API.SpaceServiceContext & API.BlobServiceContext & API.IndexServiceContext & API.UsageServiceContext} ctx */ export const createService = (ctx) => ({ info: Provider.provide(Space.info, (input) => info(input, ctx)), blob: createBlobService(ctx), index: createIndexService(ctx), + content: { serve: { egress: { record: provideRecordEgress(ctx) } } }, }) diff --git a/packages/upload-api/src/space/info.js b/packages/upload-api/src/space/info.js index bbec2eb15..94a78d88a 100644 --- a/packages/upload-api/src/space/info.js +++ b/packages/upload-api/src/space/info.js @@ -1,4 +1,4 @@ -import { Space } from '@web3-storage/capabilities' +import { Space } from '@storacha/capabilities' import { DID } from '@ucanto/validator' import * as API from '../types.js' @@ -33,7 +33,7 @@ export const info = async ({ capability }, ctx) => { } } - /** @type {import('@web3-storage/access/types').SpaceUnknown} */ + /** @type {import('@storacha/access/types').SpaceUnknown} */ const spaceUnknownFailure = { name: 'SpaceUnknown', message: `Space not found.`, diff --git a/packages/upload-api/src/usage/record.js b/packages/upload-api/src/space/record.js similarity index 70% rename from packages/upload-api/src/usage/record.js rename to packages/upload-api/src/space/record.js index f1d5b56bd..768a61ba1 100644 --- a/packages/upload-api/src/usage/record.js +++ b/packages/upload-api/src/space/record.js @@ -1,17 +1,17 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Usage } from '@web3-storage/capabilities' +import { Space } from '@storacha/capabilities' -/** @param {API.UsageServiceContext} context */ +/** @param {API.SpaceServiceContext & API.UsageServiceContext} context */ export const provide = (context) => - Provider.provide(Usage.record, (input) => record(input, context)) + Provider.provide(Space.egressRecord, (input) => egressRecord(input, context)) /** - * @param {API.Input} input - * @param {API.UsageServiceContext} context + * @param {API.Input} input + * @param {API.SpaceServiceContext & API.UsageServiceContext} context * @returns {Promise>} */ -const record = async ({ capability, invocation }, context) => { +const egressRecord = async ({ capability, invocation }, context) => { const provider = /** @type {`did:web:${string}`} */ ( invocation.audience.did() ) @@ -33,7 +33,7 @@ const record = async ({ capability, invocation }, context) => { // Number of bytes that were served. capability.nb.bytes, // Date and time when the resource was served. - new Date(capability.nb.servedAt * 1000), + new Date(capability.nb.servedAt), // Link to the invocation that caused the egress traffic. invocation.cid ) diff --git a/packages/upload-api/src/store.js b/packages/upload-api/src/store.js deleted file mode 100644 index 146bcf09c..000000000 --- a/packages/upload-api/src/store.js +++ /dev/null @@ -1,17 +0,0 @@ -import { storeAddProvider } from './store/add.js' -import { storeGetProvider } from './store/get.js' -import { storeListProvider } from './store/list.js' -import { storeRemoveProvider } from './store/remove.js' -import * as API from './types.js' - -/** - * @param {API.StoreServiceContext} context - */ -export function createService(context) { - return { - add: storeAddProvider(context), - get: storeGetProvider(context), - list: storeListProvider(context), - remove: storeRemoveProvider(context), - } -} diff --git a/packages/upload-api/src/store/add.js b/packages/upload-api/src/store/add.js deleted file mode 100644 index 76a2dbeba..000000000 --- a/packages/upload-api/src/store/add.js +++ /dev/null @@ -1,85 +0,0 @@ -import * as Server from '@ucanto/server' -import * as Store from '@web3-storage/capabilities/store' -import * as API from '../types.js' -import { allocate } from '../space-allocate.js' - -/** - * @param {API.StoreServiceContext} context - * @returns {API.ServiceMethod} - */ -export function storeAddProvider(context) { - const { storeTable, carStoreBucket, maxUploadSize } = context - return Server.provide(Store.add, async ({ capability, invocation }) => { - const { link, origin, size } = capability.nb - - if (size > maxUploadSize) { - return { - error: new Server.Failure( - `Maximum size exceeded: ${maxUploadSize}, split DAG into smaller shards.` - ), - } - } - - const space = /** @type {import('@ucanto/interface').DIDKey} */ ( - Server.DID.parse(capability.with).did() - ) - - const [allocated, carExists] = await Promise.all([ - allocate( - { - capability: { - with: space, - }, - }, - context - ), - carStoreBucket.has(link), - ]) - - // If failed to allocate space, fail with allocation error - if (allocated.error) { - return allocated - } - - let allocatedSize = size - const res = await storeTable.insert({ - space, - link, - size, - origin, - invocation: invocation.cid, - }) - if (res.error) { - // if the insert failed with conflict then this item has already been - // added to the space and there is no allocation change. - if (res.error.name === 'RecordKeyConflict') { - allocatedSize = 0 - } else { - return res - } - } - - if (carExists) { - return { - ok: { - status: 'done', - allocated: allocatedSize, - with: space, - link, - }, - } - } - - const { url, headers } = await carStoreBucket.createUploadUrl(link, size) - return { - ok: { - status: 'upload', - allocated: allocatedSize, - with: space, - link, - url: url.toString(), - headers, - }, - } - }) -} diff --git a/packages/upload-api/src/store/get.js b/packages/upload-api/src/store/get.js deleted file mode 100644 index a9e5862fb..000000000 --- a/packages/upload-api/src/store/get.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as Server from '@ucanto/server' -import * as Store from '@web3-storage/capabilities/store' -import * as API from '../types.js' -import { StoreItemNotFound } from './lib.js' - -/** - * @param {API.StoreServiceContext} context - * @returns {API.ServiceMethod} - */ -export function storeGetProvider(context) { - return Server.provide(Store.get, async ({ capability }) => { - const { link } = capability.nb - if (!link) { - return Server.fail('nb.link must be set') - } - const space = Server.DID.parse(capability.with).did() - const res = await context.storeTable.get(space, link) - if (res.error && res.error.name === 'RecordNotFound') { - return Server.error(new StoreItemNotFound(space, link)) - } - return res - }) -} diff --git a/packages/upload-api/src/store/lib.js b/packages/upload-api/src/store/lib.js deleted file mode 100644 index e66063c49..000000000 --- a/packages/upload-api/src/store/lib.js +++ /dev/null @@ -1,29 +0,0 @@ -import { Failure } from '@ucanto/server' - -export class StoreItemNotFound extends Failure { - /** - * @param {import('@ucanto/interface').DID} space - * @param {import('@ucanto/interface').UnknownLink} link - */ - constructor(space, link) { - super() - this.space = space - this.link = link - } - - get name() { - return 'StoreItemNotFound' - } - - describe() { - return `${this.link} not found in ${this.space}` - } - - toJSON() { - return { - ...super.toJSON(), - space: this.space, - link: { '/': this.link.toString() }, - } - } -} diff --git a/packages/upload-api/src/store/list.js b/packages/upload-api/src/store/list.js deleted file mode 100644 index 16466b893..000000000 --- a/packages/upload-api/src/store/list.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as Server from '@ucanto/server' -import * as Store from '@web3-storage/capabilities/store' -import * as API from '../types.js' - -/** - * @param {API.StoreServiceContext} context - * @returns {API.ServiceMethod} - */ -export function storeListProvider(context) { - return Server.provide(Store.list, async ({ capability }) => { - const { cursor, size, pre } = capability.nb - const space = Server.DID.parse(capability.with).did() - return await context.storeTable.list(space, { size, cursor, pre }) - }) -} diff --git a/packages/upload-api/src/store/remove.js b/packages/upload-api/src/store/remove.js deleted file mode 100644 index 3081c924f..000000000 --- a/packages/upload-api/src/store/remove.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as Server from '@ucanto/server' -import * as Store from '@web3-storage/capabilities/store' -import * as API from '../types.js' -import { StoreItemNotFound } from './lib.js' - -/** - * @param {API.StoreServiceContext} context - * @returns {API.ServiceMethod} - */ -export function storeRemoveProvider(context) { - return Server.provide(Store.remove, async ({ capability }) => { - const { link } = capability.nb - const space = Server.DID.parse(capability.with).did() - - const res = await context.storeTable.remove(space, link) - if (res.error && res.error.name === 'RecordNotFound') { - return Server.error(new StoreItemNotFound(space, link)) - } - - return res - }) -} diff --git a/packages/upload-api/src/subscription/get.js b/packages/upload-api/src/subscription/get.js index 817357f2a..6cc677795 100644 --- a/packages/upload-api/src/subscription/get.js +++ b/packages/upload-api/src/subscription/get.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Server from '@ucanto/server' -import { Subscription } from '@web3-storage/capabilities' +import { Subscription } from '@storacha/capabilities' /** * @param {API.SubscriptionServiceContext} context diff --git a/packages/upload-api/src/subscription/list.js b/packages/upload-api/src/subscription/list.js index 61156e1b5..e3777677e 100644 --- a/packages/upload-api/src/subscription/list.js +++ b/packages/upload-api/src/subscription/list.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Server from '@ucanto/server' -import { Subscription } from '@web3-storage/capabilities' +import { Subscription } from '@storacha/capabilities' /** * @param {API.SubscriptionServiceContext} context diff --git a/packages/upload-api/src/types.ts b/packages/upload-api/src/types.ts index c56d9a893..d409e98f7 100644 --- a/packages/upload-api/src/types.ts +++ b/packages/upload-api/src/types.ts @@ -28,11 +28,17 @@ import type { Variant, HTTPRequest, HTTPResponse, + PrincipalResolver, } from '@ucanto/interface' import type { ProviderInput, ConnectionView } from '@ucanto/server' -import { StorefrontService } from '@web3-storage/filecoin-api/types' -import { ServiceContext as FilecoinServiceContext } from '@web3-storage/filecoin-api/storefront/api' +import { StorefrontService } from '@storacha/filecoin-api/types' +import { ServiceContext as FilecoinServiceContext } from '@storacha/filecoin-api/storefront/api' +import { + Service as LegacyService, + StoreServiceContext as LegacyStoreServiceContext, + AdminServiceContext as LegacyAdminServiceContext +} from '@web3-storage/upload-api' import { DelegationsStorage as Delegations } from './types/delegations.js' import { ProvisionsStorage as Provisions } from './types/provisions.js' import { RateLimitsStorage as RateLimits } from './types/rate-limits.js' @@ -65,33 +71,18 @@ export interface DebugEmail extends Email { } import { - BlobAdd, - BlobAddSuccess, - BlobAddFailure, - BlobList, - BlobListSuccess, - BlobListFailure, - BlobRemove, - BlobRemoveSuccess, - BlobRemoveFailure, - BlobGet, - BlobGetSuccess, - BlobGetFailure, - BlobAllocate, - BlobAllocateSuccess, - BlobAllocateFailure, - BlobAccept, - BlobAcceptSuccess, - BlobAcceptFailure, - StoreAdd, - StoreGet, - StoreAddSuccess, - StoreRemove, - StoreRemoveSuccess, - StoreRemoveFailure, - StoreList, - StoreListSuccess, - StoreListItem, + SpaceBlobAdd, + SpaceBlobAddSuccess, + SpaceBlobAddFailure, + SpaceBlobList, + SpaceBlobListSuccess, + SpaceBlobListFailure, + SpaceBlobRemove, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure, + SpaceBlobGet, + SpaceBlobGetSuccess, + SpaceBlobGetFailure, UploadAdd, UploadGet, UploadAddSuccess, @@ -135,9 +126,6 @@ import { RateLimitList, RateLimitListSuccess, RateLimitListFailure, - AdminStoreInspect, - AdminStoreInspectSuccess, - AdminStoreInspectFailure, AdminUploadInspect, AdminUploadInspectSuccess, AdminUploadInspectFailure, @@ -146,12 +134,10 @@ import { ProviderAddFailure, SpaceInfo, ProviderDID, - StoreGetFailure, + UploadGetSuccess, UploadGetFailure, ListResponse, CARLink, - StoreGetSuccess, - UploadGetSuccess, UCANConclude, UCANConcludeSuccess, UCANConcludeFailure, @@ -171,17 +157,21 @@ import { PlanCreateAdminSession, PlanCreateAdminSessionSuccess, PlanCreateAdminSessionFailure, - IndexAdd, - IndexAddSuccess, - IndexAddFailure, -} from '@web3-storage/capabilities/types' -import * as Capabilities from '@web3-storage/capabilities' + SpaceIndexAdd, + SpaceIndexAddSuccess, + SpaceIndexAddFailure, +} from '@storacha/capabilities/types' +import * as Capabilities from '@storacha/capabilities' import { RevocationsStorage } from './types/revocations.js' -export * from '@web3-storage/capabilities/types' +export * from '@storacha/capabilities/types' export * from '@ucanto/interface' -export type { ProvisionsStorage, Provision } from './types/provisions.js' +export type { + ProvisionsStorage, + Provision, + Subscription, +} from './types/provisions.js' export type { DelegationsStorage, Query as DelegationsStorageQuery, @@ -200,14 +190,13 @@ export type { SubscriptionsStorage } import { UsageStorage } from './types/usage.js' export type { UsageStorage } import { StorageGetError } from './types/storage.js' -import { AllocationsStorage, BlobsStorage, BlobAddInput } from './types/blob.js' -export type { AllocationsStorage, BlobsStorage, BlobAddInput } -import { IPNIService, IndexServiceContext } from './types/index.js' +import { Registry as BlobRegistry, RoutingService } from './types/blob.js' +export type * as BlobAPI from './types/blob.js' +import { IndexServiceContext } from './types/index.js' import { ClaimsClientConfig } from './types/content-claims.js' import { Claim } from '@web3-storage/content-claims/client/api' export type { IndexServiceContext, - IPNIService, BlobRetriever, BlobNotFound, ShardedDAGIndex, @@ -219,13 +208,7 @@ export type { Service as ClaimsService, } from './types/content-claims.js' -export interface Service extends StorefrontService, W3sService { - store: { - add: ServiceMethod - get: ServiceMethod - remove: ServiceMethod - list: ServiceMethod - } +export interface Service extends StorefrontService { upload: { add: ServiceMethod get: ServiceMethod @@ -294,7 +277,6 @@ export interface Service extends StorefrontService, W3sService { RateLimitListFailure > } - ucan: { conclude: ServiceMethod< UCANConclude, @@ -303,15 +285,8 @@ export interface Service extends StorefrontService, W3sService { > revoke: ServiceMethod } - admin: { - store: { - inspect: ServiceMethod< - AdminStoreInspect, - AdminStoreInspectSuccess, - AdminStoreInspectFailure - > - } + store: LegacyService['admin']['store'] upload: { inspect: ServiceMethod< AdminUploadInspect, @@ -326,15 +301,31 @@ export interface Service extends StorefrontService, W3sService { space: { info: ServiceMethod index: { - add: ServiceMethod + add: ServiceMethod< + SpaceIndexAdd, + SpaceIndexAddSuccess, + SpaceIndexAddFailure + > } blob: { - add: ServiceMethod - remove: ServiceMethod - list: ServiceMethod + add: ServiceMethod + remove: ServiceMethod< + SpaceBlobRemove, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure + > + list: ServiceMethod< + SpaceBlobList, + SpaceBlobListSuccess, + SpaceBlobListFailure + > get: { 0: { - 1: ServiceMethod + 1: ServiceMethod< + SpaceBlobGet, + SpaceBlobGetSuccess, + SpaceBlobGetFailure + > } } } @@ -351,19 +342,8 @@ export interface Service extends StorefrontService, W3sService { usage: { report: ServiceMethod } -} - -export interface W3sService { - ['web3.storage']: { - blob: { - allocate: ServiceMethod< - BlobAllocate, - BlobAllocateSuccess, - BlobAllocateFailure - > - accept: ServiceMethod - } - } + // legacy handlers + store: LegacyService['store'] } export type BlobServiceContext = SpaceServiceContext & { @@ -371,26 +351,9 @@ export type BlobServiceContext = SpaceServiceContext & { * Service signer */ id: Signer - maxUploadSize: number - allocationsStorage: AllocationsStorage - blobsStorage: BlobsStorage agentStore: AgentStore - getServiceConnection: () => ConnectionView -} - -export type W3ServiceContext = SpaceServiceContext & { - /** - * Service signer - */ - id: Signer - allocationsStorage: AllocationsStorage - blobsStorage: BlobsStorage -} - -export type StoreServiceContext = SpaceServiceContext & { - maxUploadSize: number - storeTable: StoreTable - carStoreBucket: CarStoreBucket + router: RoutingService + registry: BlobRegistry } export type UploadServiceContext = ConsumerServiceContext & @@ -426,7 +389,7 @@ export interface CustomerServiceContext { export interface AdminServiceContext { signer: Signer uploadTable: UploadTable - storeTable: StoreTable + storeTable: LegacyAdminServiceContext['storeTable'] } export interface ConsoleServiceContext {} @@ -459,17 +422,14 @@ export interface RevocationServiceContext { } export interface ConcludeServiceContext { - /** - * Service signer - */ + /** Upload service signer. */ id: Signer - /** * Store for invocations & receipts. */ agentStore: AgentStore - - getServiceConnection: () => ConnectionView + registry: BlobRegistry + router: RoutingService } export interface PlanServiceContext { @@ -482,14 +442,14 @@ export interface UsageServiceContext { } export interface ServiceContext - extends AgentContext, + extends AdminServiceContext, + AgentContext, AccessServiceContext, ConsoleServiceContext, ConsumerServiceContext, CustomerServiceContext, ProviderServiceContext, SpaceServiceContext, - StoreServiceContext, BlobServiceContext, ConcludeServiceContext, SubscriptionServiceContext, @@ -499,9 +459,10 @@ export interface ServiceContext UploadServiceContext, FilecoinServiceContext, IndexServiceContext, - UsageServiceContext {} + UsageServiceContext, + LegacyStoreServiceContext {} -export interface UcantoServerContext extends ServiceContext, RevocationChecker { +export interface UcantoServerContext extends ServiceContext, RevocationChecker, PrincipalResolver { id: Signer codec?: InboundCodec errorReporter: ErrorReporter @@ -594,13 +555,8 @@ export interface UcantoServerTestContext grantAccess: (mail: { url: string | URL }) => Promise - ipniService: IPNIService & { - query(digest: MultihashDigest): Promise> - } - - carStoreBucket: CarStoreBucket & Deactivator - blobsStorage: BlobsStorage & Deactivator claimsService: ClaimsClientConfig & ClaimReader & Deactivator + storageProviders: Deactivator[] } export interface ClaimReader { @@ -619,33 +575,6 @@ export interface ErrorReporter { catch: (error: HandlerExecutionError | WriteError) => void } -export interface CarStoreBucket { - has: (link: UnknownLink) => Promise - createUploadUrl: ( - link: UnknownLink, - size: number - ) => Promise<{ - url: URL - headers: { - 'x-amz-checksum-sha256': string - 'content-length': string - } & Record - }> -} - -export interface CarStoreBucketOptions { - accessKeyId?: string - secretAccessKey?: string - region?: string - bucket?: string - sessionToken?: string - expires?: number -} - -export interface CarStoreBucketService { - use(options?: CarStoreBucketOptions): Promise -} - /** * Indicates the requested record was not present in the table. */ @@ -661,28 +590,6 @@ export interface RecordKeyConflict extends Failure { name: 'RecordKeyConflict' } -export interface StoreTable { - inspect: (link: UnknownLink) => Promise> - exists: (space: DID, link: UnknownLink) => Promise> - get: ( - space: DID, - link: UnknownLink - ) => Promise> - /** Inserts an item in the table if it does not already exist. */ - insert: ( - item: StoreAddInput - ) => Promise> - /** Removes an item from the table but fails if the item does not exist. */ - remove: ( - space: DID, - link: UnknownLink - ) => Promise> - list: ( - space: DID, - options?: ListOptions - ) => Promise, Failure>> -} - export interface UploadTable { inspect: (link: UnknownLink) => Promise> exists: (space: DID, root: UnknownLink) => Promise> @@ -720,42 +627,17 @@ export type SubscriptionGetResult = Result< SubscriptionGetSuccess, SubscriptionGetFailure > -export type AdminStoreInspectResult = Result< - AdminStoreInspectSuccess, - AdminStoreInspectFailure -> export type AdminUploadInspectResult = Result< AdminUploadInspectSuccess, AdminUploadInspectFailure > -export interface StoreAddInput { - space: DID - link: CARLink - size: number - origin?: UnknownLink - - /** - * @deprecated - Issuer of the invocation is irrelevant as long as - * they have authorization to invoke on subject `space`. - */ - issuer?: DID - invocation: UCANLink -} - -export interface StoreAddOutput - extends Omit {} - -export interface StoreInspectSuccess { - spaces: Array<{ did: DID; insertedAt: string }> -} - export interface UploadAddInput { space: DID root: UnknownLink shards?: CARLink[] issuer: DID - invocation: UCANLink + cause: UCANLink } export interface UploadInspectSuccess { diff --git a/packages/upload-api/src/types/blob.ts b/packages/upload-api/src/types/blob.ts index a12464424..d2569e1a3 100644 --- a/packages/upload-api/src/types/blob.ts +++ b/packages/upload-api/src/types/blob.ts @@ -1,46 +1,66 @@ import type { UnknownLink, + Link, Invocation, Result, Failure, - DID, - URI, + Capability, + ServiceMethod, + UCANOptions, + IssuedInvocationView, + ConnectionView, + Principal, + Unit, } from '@ucanto/interface' import { Multihash, - BlobListItem, - BlobRemoveSuccess, - BlobGetSuccess, -} from '@web3-storage/capabilities/types' + BlobAllocate, + BlobAccept, + BlobAllocateSuccess, + BlobAcceptSuccess, +} from '@storacha/capabilities/types' import { MultihashDigest } from 'multiformats' - -import { RecordKeyConflict, ListResponse } from '../types.js' +import { ListResponse, SpaceDID } from '../types.js' import { Storage } from './storage.js' +export interface Blob { + digest: MultihashDigest + size: number +} + +export interface Entry { + blob: Blob + cause: Link + insertedAt: Date +} + +/** Indicates an entry was not found that matches the passed details. */ +export interface EntryNotFound extends Failure { + name: 'EntryNotFound' +} + +/** Indicates an entry has already been registered for the passed details. */ +export interface EntryExists extends Failure { + name: 'EntryExists' +} + export type TasksStorage = Storage -export interface AllocationsStorage { - get: ( - space: DID, - digest: MultihashDigest - ) => Promise> - exists: ( - space: DID, +export interface Registry { + /** Lookup an existing registration. */ + find: ( + space: SpaceDID, digest: MultihashDigest - ) => Promise> - /** Inserts an item in the table if it does not already exist. */ - insert: ( - item: BlobAddInput - ) => Promise> - list: ( - space: DID, + ) => Promise> + /** Adds an item into the registry if it does not already exist. */ + register: (item: RegistrationData) => Promise> + /** List entries in the registry for a given space. */ + entries: ( + space: SpaceDID, options?: ListOptions - ) => Promise, Failure>> - /** Removes an item from the table, returning zero on size if non existent. */ - remove: ( - space: DID, - digest: MultihashDigest - ) => Promise> + ) => Promise, Failure>> + /** Removes an item from the registry if it exists. */ + deregister: (item: DeregistrationData) => Promise> } export interface ListOptions { @@ -53,34 +73,68 @@ export interface BlobModel { size: number } -export interface BlobAddInput { - space: DID - cause: UnknownLink - blob: BlobModel +export interface DeregistrationData { + space: SpaceDID, + digest: MultihashDigest, + cause: Link +} + +export interface RegistrationData { + space: SpaceDID + cause: Link + blob: Blob +} + +export interface BlobService { + blob: { + allocate: ServiceMethod + accept: ServiceMethod + } } -export interface BlobAddOutput extends Omit {} +export interface Configuration { + /** Connection to the storage node. */ + connection: ConnectionView + /** Invocation to execute. */ + invocation: IssuedInvocationView +} + +/** + * An unavailable proof error is returned when the routing does not have a + * valid unexpired and unrevoked proof available. + */ +export interface ProofUnavailable extends Failure { + name: 'ProofUnavailable' +} + +/** + * An unavailable candidate error is returned when there are no candidates + * willing to allocate space for the given blob. + */ +export interface CandidateUnavailable extends Failure { + name: 'CandidateUnavailable' +} -export interface BlobsStorage { - has: (content: MultihashDigest) => Promise> - createUploadUrl: ( - content: MultihashDigest, - size: number, - /** - * The number of seconds before the presigned URL expires - */ - expiresIn: number - ) => Promise< - Result< - { - url: URL - headers: { - 'x-amz-checksum-sha256': string - 'content-length': string - } & Record - }, - Failure - > - > - createDownloadUrl: (content: MultihashDigest) => Promise> +/** + * The routing service is responsible for selecting storage nodes to allocate + * blobs with. + */ +export interface RoutingService { + /** + * Selects a candidate for blob allocation from the current list of available + * storage nodes. + */ + selectStorageProvider( + digest: MultihashDigest, + size: number + ): Promise> + /** + * Returns information required to make an invocation to the requested storage + * node. + */ + configureInvocation( + provider: Principal, + capability: C, + options?: Omit + ): Promise, ProofUnavailable | Failure>> } diff --git a/packages/upload-api/src/types/index.ts b/packages/upload-api/src/types/index.ts index 2aaf4c89a..eb0ed01c8 100644 --- a/packages/upload-api/src/types/index.ts +++ b/packages/upload-api/src/types/index.ts @@ -1,20 +1,11 @@ import { MultihashDigest } from 'multiformats' -import { Failure, Result, Unit } from '@ucanto/interface' -import { ShardedDAGIndex } from '@web3-storage/blob-index/types' -import { AllocationsStorage } from './blob.js' +import { Failure, Result } from '@ucanto/interface' +import { ShardedDAGIndex } from '@storacha/blob-index/types' +import { Registry } from './blob.js' import { ClaimsClientContext } from './content-claims.js' export type { ShardedDAGIndex, ClaimsClientContext } -/** - * Service that allows publishing a set of multihashes to IPNI for a - * pre-configured provider. - */ -export interface IPNIService { - /** Publish the multihashes in the provided index to IPNI. */ - publish(index: ShardedDAGIndex): Promise> -} - export interface BlobNotFound extends Failure { name: 'BlobNotFound' digest: Uint8Array @@ -28,7 +19,6 @@ export interface BlobRetriever { } export interface IndexServiceContext extends ClaimsClientContext { - allocationsStorage: AllocationsStorage blobRetriever: BlobRetriever - ipniService: IPNIService + registry: Registry } diff --git a/packages/upload-api/src/types/provisions.ts b/packages/upload-api/src/types/provisions.ts index a2046c0b0..1ebff1697 100644 --- a/packages/upload-api/src/types/provisions.ts +++ b/packages/upload-api/src/types/provisions.ts @@ -2,9 +2,9 @@ import type { AccountDID, ConsumerGetSuccess, ProviderDID, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' import * as Ucanto from '@ucanto/interface' -import { ProviderAdd } from '@web3-storage/capabilities/types' +import { ProviderAdd } from '@storacha/capabilities/types' import { SpaceDID } from '../types.js' /** diff --git a/packages/upload-api/src/types/storage.ts b/packages/upload-api/src/types/storage.ts index ce4e3a39b..a252271c4 100644 --- a/packages/upload-api/src/types/storage.ts +++ b/packages/upload-api/src/types/storage.ts @@ -1,8 +1,5 @@ import type { Unit, Result } from '@ucanto/interface' -import { - StorageGetError, - StoragePutError, -} from '@web3-storage/capabilities/types' +import { StorageGetError, StoragePutError } from '@storacha/capabilities/types' export type { StorageGetError, StoragePutError } diff --git a/packages/upload-api/src/types/subscriptions.ts b/packages/upload-api/src/types/subscriptions.ts index 6053e8262..f179b304b 100644 --- a/packages/upload-api/src/types/subscriptions.ts +++ b/packages/upload-api/src/types/subscriptions.ts @@ -3,7 +3,7 @@ import { AccountDID, SubscriptionListSuccess, SubscriptionListFailure, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' export interface SubscriptionsStorage { list: ( diff --git a/packages/upload-api/src/types/usage.ts b/packages/upload-api/src/types/usage.ts index bd08a48cd..6aff2a14e 100644 --- a/packages/upload-api/src/types/usage.ts +++ b/packages/upload-api/src/types/usage.ts @@ -5,7 +5,7 @@ import { SpaceDID, UsageData, EgressData, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' export type { UsageData } @@ -27,6 +27,6 @@ export interface UsageStorage { /** The date and time when the resource was served. */ servedAt: Date, /** Identifier of the invocation that caused the egress traffic. */ - cause: UnknownLink, + cause: UnknownLink ) => Promise> } diff --git a/packages/upload-api/src/ucan/conclude.js b/packages/upload-api/src/ucan/conclude.js index 1c0e4a1e4..7ca5e1d96 100644 --- a/packages/upload-api/src/ucan/conclude.js +++ b/packages/upload-api/src/ucan/conclude.js @@ -1,7 +1,7 @@ import * as API from '../types.js' import { provide } from '@ucanto/server' import { Receipt } from '@ucanto/core' -import { conclude } from '@web3-storage/capabilities/ucan' +import { conclude } from '@storacha/capabilities/ucan' import * as BlobAccept from '../blob/accept.js' /** @@ -49,7 +49,7 @@ export function getConcludeReceipt(concludeFx) { /** * @param {API.Signer} id - * @param {API.Verifier} serviceDid + * @param {API.Principal} serviceDid * @param {API.Receipt} receipt */ export function createConcludeInvocation(id, serviceDid, receipt) { diff --git a/packages/upload-api/src/ucan/revoke.js b/packages/upload-api/src/ucan/revoke.js index 8b8636a2d..7ab61cb8d 100644 --- a/packages/upload-api/src/ucan/revoke.js +++ b/packages/upload-api/src/ucan/revoke.js @@ -1,5 +1,5 @@ import { provide, Delegation, Failure } from '@ucanto/server' -import { revoke } from '@web3-storage/capabilities/ucan' +import { revoke } from '@storacha/capabilities/ucan' import * as API from '../types.js' /** diff --git a/packages/upload-api/src/upload/add.js b/packages/upload-api/src/upload/add.js index ff343b245..80084aef7 100644 --- a/packages/upload-api/src/upload/add.js +++ b/packages/upload-api/src/upload/add.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Upload from '@storacha/capabilities/upload' import * as API from '../types.js' import { allocate } from '../space-allocate.js' @@ -32,7 +32,7 @@ export function uploadAddProvider(context) { root, shards, issuer, - invocation: invocation.cid, + cause: invocation.cid, }) }) } diff --git a/packages/upload-api/src/upload/get.js b/packages/upload-api/src/upload/get.js index e76a3fdcc..b7c85f9ba 100644 --- a/packages/upload-api/src/upload/get.js +++ b/packages/upload-api/src/upload/get.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Upload from '@storacha/capabilities/upload' import * as API from '../types.js' import { UploadNotFound } from './lib.js' diff --git a/packages/upload-api/src/upload/list.js b/packages/upload-api/src/upload/list.js index 375eacc78..f1e536bb9 100644 --- a/packages/upload-api/src/upload/list.js +++ b/packages/upload-api/src/upload/list.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Upload from '@storacha/capabilities/upload' import * as API from '../types.js' /** diff --git a/packages/upload-api/src/upload/remove.js b/packages/upload-api/src/upload/remove.js index f7e42e299..603a978c5 100644 --- a/packages/upload-api/src/upload/remove.js +++ b/packages/upload-api/src/upload/remove.js @@ -1,5 +1,5 @@ import * as Server from '@ucanto/server' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Upload from '@storacha/capabilities/upload' import * as API from '../types.js' import { UploadNotFound } from './lib.js' diff --git a/packages/upload-api/src/usage.js b/packages/upload-api/src/usage.js index 8cea68010..2600acbf4 100644 --- a/packages/upload-api/src/usage.js +++ b/packages/upload-api/src/usage.js @@ -1,8 +1,6 @@ import { provide as provideReport } from './usage/report.js' -import { provide as provideRecord } from './usage/record.js' /** @param {import('./types.js').UsageServiceContext} context */ export const createService = (context) => ({ report: provideReport(context), - record: provideRecord(context), }) diff --git a/packages/upload-api/src/usage/report.js b/packages/upload-api/src/usage/report.js index 05bc35629..46ccff83a 100644 --- a/packages/upload-api/src/usage/report.js +++ b/packages/upload-api/src/usage/report.js @@ -1,6 +1,6 @@ import * as API from '../types.js' import * as Provider from '@ucanto/server' -import { Usage } from '@web3-storage/capabilities' +import { Usage } from '@storacha/capabilities' /** @param {API.UsageServiceContext} context */ export const provide = (context) => diff --git a/packages/upload-api/src/utils/delegations-response.js b/packages/upload-api/src/utils/delegations-response.js index 6a0a46109..cce46f23e 100644 --- a/packages/upload-api/src/utils/delegations-response.js +++ b/packages/upload-api/src/utils/delegations-response.js @@ -7,7 +7,7 @@ import * as Ucanto from '@ucanto/interface' import { bytesToDelegations, delegationsToBytes, -} from '@web3-storage/access/encoding' +} from '@storacha/access/encoding' /** * @template D @@ -37,7 +37,7 @@ export function encode(delegations) { export function* decode(encoded) { for (const carBytes of Object.values(encoded)) { const delegations = bytesToDelegations( - /** @type {import('@web3-storage/access/types').BytesDelegation} */ ( + /** @type {import('@storacha/access/types').BytesDelegation} */ ( carBytes ) ) diff --git a/packages/upload-api/src/utils/did-mailto.js b/packages/upload-api/src/utils/did-mailto.js index 35317d6e6..97301897d 100644 --- a/packages/upload-api/src/utils/did-mailto.js +++ b/packages/upload-api/src/utils/did-mailto.js @@ -1,14 +1,14 @@ -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' /** - * @param {import("@web3-storage/did-mailto/types").DidMailto} mailtoDid + * @param {import("@storacha/did-mailto/types").DidMailto} mailtoDid */ export function mailtoDidToEmail(mailtoDid) { return DidMailto.toEmail(DidMailto.fromString(mailtoDid)) } /** - * @param {import("@web3-storage/did-mailto/types").DidMailto} mailtoDid + * @param {import("@storacha/did-mailto/types").DidMailto} mailtoDid */ export function mailtoDidToDomain(mailtoDid) { const accountEmail = mailtoDidToEmail(mailtoDid) diff --git a/packages/upload-api/src/validate.js b/packages/upload-api/src/validate.js index 33a341d23..9cdc4024e 100644 --- a/packages/upload-api/src/validate.js +++ b/packages/upload-api/src/validate.js @@ -1,8 +1,8 @@ import { delegationsToString, stringToDelegation, -} from '@web3-storage/access/encoding' -import * as DidMailto from '@web3-storage/did-mailto' +} from '@storacha/access/encoding' +import * as DidMailto from '@storacha/did-mailto' import { Verifier } from '@ucanto/principal' import * as delegationsResponse from './utils/delegations-response.js' import * as accessConfirm from './access/confirm.js' @@ -30,7 +30,7 @@ export async function authorizeFromUrl(url, env) { export async function authorize(encodedUcan, env) { try { /** - * @type {import('@ucanto/interface').Delegation<[import('@web3-storage/capabilities/types').AccessConfirm]>} + * @type {import('@ucanto/interface').Delegation<[import('@storacha/capabilities/types').AccessConfirm]>} */ const request = stringToDelegation(encodedUcan) diff --git a/packages/upload-api/test/access-client-agent.js b/packages/upload-api/test/access-client-agent.js index c6ded27e1..b0f22194b 100644 --- a/packages/upload-api/test/access-client-agent.js +++ b/packages/upload-api/test/access-client-agent.js @@ -1,11 +1,11 @@ import * as API from './types.js' import { Absentee } from '@ucanto/principal' import * as delegationsResponse from '../src/utils/delegations-response.js' -import * as DidMailto from '@web3-storage/did-mailto' -import { Access, Space, Top, UCAN } from '@web3-storage/capabilities' -import { AgentData } from '@web3-storage/access' +import * as DidMailto from '@storacha/did-mailto' +import { Access, Space, Top, UCAN } from '@storacha/capabilities' +import { AgentData } from '@storacha/access' import { alice } from './helpers/utils.js' -import { stringToDelegations } from '@web3-storage/access/encoding' +import { stringToDelegations } from '@storacha/access/encoding' import { confirmConfirmationUrl, extractConfirmInvocation, @@ -21,8 +21,8 @@ import { delegationsIncludeSessionProof, addSpacesFromDelegations, requestAccess, -} from '@web3-storage/access/agent' -import * as Provider from '@web3-storage/access/provider' +} from '@storacha/access/agent' +import * as Provider from '@storacha/access/provider' /** * Create and return a space, delegated to the device agent and to the account, @@ -80,7 +80,7 @@ const claimDelegations = async (device) => { * Assert that the device agent can invoke `space/info` on the given space. * * @param {Agent} device - * @param {import('@web3-storage/access/agent').OwnedSpace} space + * @param {import('@storacha/access/agent').OwnedSpace} space * @param {API.Assert} assert */ async function assertCanSpaceInfo(device, space, assert) { @@ -92,7 +92,7 @@ async function assertCanSpaceInfo(device, space, assert) { assert.ok(spaceInfoResult.out.ok) const result = - /** @type {import('@web3-storage/access/types').SpaceInfoResult} */ ( + /** @type {import('@storacha/access/types').SpaceInfoResult} */ ( spaceInfoResult.out.ok ) assert.deepEqual(result.did, space.did()) @@ -146,7 +146,7 @@ export const test = { ) assert.deepEqual(confirmationInvocations.length, 1) const serviceSaysAccountCanConfirm = - /** @type {API.Invocation} */ ( + /** @type {API.Invocation} */ ( confirmationInvocations[0] ) diff --git a/packages/upload-api/test/external-service/blob-retriever.js b/packages/upload-api/test/external-service/blob-retriever.js new file mode 100644 index 000000000..8f5d50e0c --- /dev/null +++ b/packages/upload-api/test/external-service/blob-retriever.js @@ -0,0 +1,25 @@ +import { ok, error } from '@ucanto/core' +import * as API from '../../src/types.js' +import { BlobNotFound } from '../../src/blob.js' + +/** + * @param {API.ClaimReader} claims + * @returns {API.BlobRetriever} + */ +export const create = (claims) => { + return { + /** @type {API.BlobRetriever['stream']} */ + async stream(digest) { + const readResult = await claims.read(digest) + if (readResult.error) throw readResult.error + for (const claim of readResult.ok) { + if (claim.type === 'assert/location') { + const res = await fetch(claim.location[0]) + if (!res.body) throw new Error('missing response body') + return ok(res.body) + } + } + return error(new BlobNotFound(digest)) + }, + } +} diff --git a/packages/upload-api/test/external-service/content-claims.js b/packages/upload-api/test/external-service/content-claims.js index 5677a46f5..03e71c69e 100644 --- a/packages/upload-api/test/external-service/content-claims.js +++ b/packages/upload-api/test/external-service/content-claims.js @@ -5,7 +5,7 @@ import { CAR, HTTP } from '@ucanto/transport' import { Assert } from '@web3-storage/content-claims/capability' import * as Client from '@web3-storage/content-claims/client' import * as Server from '@web3-storage/content-claims/server' -import { DigestMap } from '@web3-storage/blob-index' +import { DigestMap } from '@storacha/blob-index' /** * @param {object} params @@ -82,13 +82,13 @@ export const activate = async ({ http } = {}) => { chunks.push(chunk) } - const { headers, body } = await server.request({ + const { status, headers, body } = await server.request({ // @ts-expect-error headers: req.headers, body: new Uint8Array(await new Blob(chunks).arrayBuffer()), }) - res.writeHead(200, headers) + res.writeHead(status ?? 200, headers) res.write(body) res.end() }) diff --git a/packages/upload-api/test/external-service/index.js b/packages/upload-api/test/external-service/index.js index 3dc000b45..98c1e274f 100644 --- a/packages/upload-api/test/external-service/index.js +++ b/packages/upload-api/test/external-service/index.js @@ -1,11 +1,67 @@ -import { IPNIService } from './ipni.js' +import { ok, error } from '@ucanto/core' +import { DIDResolutionError } from '@ucanto/validator' import * as ClaimsService from './content-claims.js' +import { BrowserStorageNode, StorageNode } from './storage-node.js' +import * as BlobRetriever from './blob-retriever.js' +import * as RoutingService from './router.js' + +export { + ClaimsService, + BrowserStorageNode, + StorageNode, + BlobRetriever, + RoutingService, +} /** - * @param {object} [options] - * @param {import('node:http')} [options.http] + * @param {object} config + * @param {import('@ucanto/interface').Signer} config.serviceID + * @param {import('node:http')} [config.http] */ -export const getExternalServiceImplementations = async (options) => ({ - ipniService: new IPNIService(), - claimsService: await ClaimsService.activate(options), -}) +export const getExternalServiceImplementations = async (config) => { + /** @type {import('@ucanto/interface').PrincipalResolver} */ + let principalResolver = {} + if (config.serviceID.did().startsWith('did:web')) { + principalResolver.resolveDIDKey = (did) => + did === config.serviceID.did() + ? ok(config.serviceID.toDIDKey()) + : error(new DIDResolutionError(did)) + } + + const claimsService = await ClaimsService.activate(config) + const blobRetriever = BlobRetriever.create(claimsService) + const storageProviders = await Promise.all( + config.http + ? [ + StorageNode.activate({ + http: config.http, + claimsService, + ...principalResolver, + }), + StorageNode.activate({ + http: config.http, + claimsService, + ...principalResolver, + }), + ] + : [ + BrowserStorageNode.activate({ + port: 8989, + claimsService, + ...principalResolver, + }), + BrowserStorageNode.activate({ + port: 8990, + claimsService, + ...principalResolver, + }), + ] + ) + const router = RoutingService.create(config.serviceID, storageProviders) + return { + claimsService, + storageProviders, + blobRetriever, + router, + } +} diff --git a/packages/upload-api/test/external-service/ipni.js b/packages/upload-api/test/external-service/ipni.js deleted file mode 100644 index f7220b3c8..000000000 --- a/packages/upload-api/test/external-service/ipni.js +++ /dev/null @@ -1,34 +0,0 @@ -import * as API from '../../src/types.js' -import { base58btc } from 'multiformats/bases/base58' -import { ok, error } from '@ucanto/core' -import { DigestMap } from '@web3-storage/blob-index' -import { RecordNotFound } from '../../src/errors.js' - -/** @implements {API.IPNIService} */ -export class IPNIService { - #data - - constructor() { - this.#data = new DigestMap() - } - - /** @param {import('@web3-storage/blob-index/types').ShardedDAGIndex} index */ - async publish(index) { - for (const [, slices] of index.shards) { - for (const [digest] of slices) { - this.#data.set(digest, true) - } - } - return ok({}) - } - - /** @param {API.MultihashDigest} digest */ - async query(digest) { - const exists = this.#data.has(digest) - if (!exists) { - const mhstr = base58btc.encode(digest.bytes) - return error(new RecordNotFound(`advert not found: ${mhstr}`)) - } - return ok({}) - } -} diff --git a/packages/upload-api/test/external-service/router.js b/packages/upload-api/test/external-service/router.js new file mode 100644 index 000000000..ee2e15b59 --- /dev/null +++ b/packages/upload-api/test/external-service/router.js @@ -0,0 +1,83 @@ +import { ok, error, Failure } from '@ucanto/core' +import { Invocation, Delegation } from '@ucanto/core' +import { base58btc } from 'multiformats/bases/base58' + +/** + * @typedef {{ + * id: import('@ucanto/interface').Signer, + * connection: import('@ucanto/interface').Connection + * }} StorageProvider + */ + +/** @type {Map} */ +const stickySelect = new Map() + +/** + * @param {import('@ucanto/interface').Signer} serviceID + * @param {Array} storageProviders + */ +export const create = (serviceID, storageProviders) => + /** @type {import('../../src/types/blob.js').RoutingService} */ + ({ + selectStorageProvider: async (digest) => { + // ensure we pick the same provider for a given digest within a test + const key = base58btc.encode(digest.bytes) + let provider = stickySelect.get(key) + if ( + provider && + !storageProviders.some((p) => p.id.did() === provider?.did()) + ) { + provider = undefined + } + if (!provider) { + provider = storageProviders[getRandomInt(storageProviders.length)].id + stickySelect.set(key, provider) + } + return ok(provider) + }, + configureInvocation: async (provider, capability, options) => { + const prov = storageProviders.find((p) => p.id.did() === provider.did()) + if (!prov) { + return error( + new ProofUnavailableError(`unknown provider: ${provider.did()}`) + ) + } + + const proof = await Delegation.delegate({ + issuer: prov.id, + audience: serviceID, + capabilities: [capability], + expiration: Infinity, + }) + + const invocation = Invocation.invoke({ + ...options, + issuer: serviceID, + audience: provider, + capability, + proofs: [proof], + }) + return ok({ invocation, connection: prov.connection }) + }, + }) + +/** @param {number} max */ +const getRandomInt = (max) => Math.floor(Math.random() * max) + +export class ProofUnavailableError extends Failure { + static name = 'ProofUnavailable' + + get name() { + return ProofUnavailableError.name + } + + /** @param {string} [reason] */ + constructor(reason) { + super() + this.reason = reason + } + + describe() { + return this.reason ?? 'proof unavailable' + } +} diff --git a/packages/upload-api/test/external-service/storage-node.js b/packages/upload-api/test/external-service/storage-node.js new file mode 100644 index 000000000..61b94fe4c --- /dev/null +++ b/packages/upload-api/test/external-service/storage-node.js @@ -0,0 +1,347 @@ +import * as API from '../../src/types.js' +import * as BlobCapabilities from '@storacha/capabilities/blob' +import { base64pad } from 'multiformats/bases/base64' +import { Assert } from '@web3-storage/content-claims/capability' +import { base58btc } from 'multiformats/bases/base58' +import { sha256 } from 'multiformats/hashes/sha2' +import * as Digest from 'multiformats/hashes/digest' +import { ok, error } from '@ucanto/core' +import { ed25519 } from '@ucanto/principal' +import { CAR, HTTP } from '@ucanto/transport' +import * as Server from '@ucanto/server' +import { connect } from '@ucanto/client' +import { + AllocatedMemoryNotWrittenError, + BlobSizeLimitExceededError, +} from '../../src/blob.js' + +/** + * @typedef {{ + * has: (digest: API.MultihashDigest) => Promise + * get: (digest: API.MultihashDigest) => Promise + * set: (digest: API.MultihashDigest, bytes: Uint8Array) => Promise + * }} ContentStore + * @typedef {{ + * has: (digest: API.MultihashDigest) => Promise + * add: (digest: API.MultihashDigest) => Promise + * }} AllocationStore + * @typedef {import('../../src/types/blob.js').BlobService} BlobService + */ + +export const MaxUploadSize = 127 * (1 << 25) + +/** @param {API.MultihashDigest} digest */ +const contentKey = (digest) => { + const encodedMultihash = base58btc.encode(digest.bytes) + return `${encodedMultihash}/${encodedMultihash}.blob` +} + +/** @param {string} key */ +const contentDigest = (key) => + Digest.decode( + base58btc.decode(key.split('/').pop()?.replace('.blob', '') ?? '') + ) + +/** + * @param {{ + * baseURL: () => URL + * claimsService: API.ClaimsClientConfig + * contentStore: Omit + * allocationStore: AllocationStore + * }} config + * @returns {BlobService} + */ +const createService = ({ + baseURL, + claimsService, + contentStore, + allocationStore, +}) => ({ + blob: { + allocate: Server.provideAdvanced({ + capability: BlobCapabilities.allocate, + handler: async ({ capability }) => { + const digest = Digest.decode(capability.nb.blob.digest) + const checksum = base64pad.baseEncode(digest.digest) + if (capability.nb.blob.size > MaxUploadSize) { + return error( + new BlobSizeLimitExceededError( + capability.nb.blob.size, + MaxUploadSize + ) + ) + } + if (await contentStore.has(digest)) { + return ok({ size: 0 }) + } + + const size = (await allocationStore.has(digest)) + ? 0 + : capability.nb.blob.size + await allocationStore.add(digest) + + return ok({ + size, + address: { + url: new URL(contentKey(digest), baseURL()).toString(), + headers: { 'x-amz-checksum-sha256': checksum }, + expires: 60 * 60 * 24, + }, + }) + }, + }), + accept: Server.provideAdvanced({ + capability: BlobCapabilities.accept, + handler: async ({ capability }) => { + const digest = Digest.decode(capability.nb.blob.digest) + if (!(await contentStore.has(digest))) { + return error(new AllocatedMemoryNotWrittenError()) + } + + const receipt = await publishLocationCommitment( + { claimsService }, + { + space: capability.nb.space, + digest, + location: + /** @type {API.URI} */ + (new URL(contentKey(digest), baseURL()).toString()), + } + ) + if (receipt.out.error) { + return receipt.out + } + + return Server.ok({ site: receipt.ran.link() }).fork(receipt.ran) + }, + }), + }, +}) + +// The browser storage node has an external bucket where data is sent, started +// before the browser tests begin. +export class BrowserStorageNode { + /** @param {{ port?: number, claimsService: API.ClaimsClientConfig } & import('@ucanto/interface').PrincipalResolver} config */ + static async activate({ claimsService, resolveDIDKey, port }) { + const id = await ed25519.generate() + const baseURL = new URL(`http://127.0.0.1:${port ?? 8989}`) + + const contentStore = { + /** @param {API.MultihashDigest} digest */ + has: async (digest) => { + const res = await fetch(new URL(contentKey(digest), baseURL)) + return res.status === 200 + }, + /** @param {API.MultihashDigest} digest */ + get: async (digest) => { + const res = await fetch(new URL(contentKey(digest), baseURL)) + return res.status === 200 + ? new Uint8Array(await res.arrayBuffer()) + : undefined + }, + } + + const allocations = new Set() + const allocationStore = { + /** @param {API.MultihashDigest} digest */ + has: async (digest) => allocations.has(contentKey(digest)), + /** @param {API.MultihashDigest} digest */ + add: async (digest) => { + allocations.add(contentKey(digest)) + }, + } + + const server = Server.create({ + id, + codec: CAR.inbound, + service: createService({ + baseURL: () => baseURL, + claimsService, + contentStore, + allocationStore, + }), + resolveDIDKey, + validateAuthorization: () => ({ ok: {} }), + }) + + const connection = connect({ id, codec: CAR.outbound, channel: server }) + + return new BrowserStorageNode({ id, baseURL, connection }) + } + + /** + * @param {{ + * id: API.Signer + * connection: import('@ucanto/interface').ConnectionView + * baseURL: URL + * }} config + */ + constructor({ id, baseURL, connection }) { + this.id = id + this.baseURL = baseURL + this.connection = connection + } + + async deactivate() { + try { + await fetch(new URL('/reset', this.baseURL), { method: 'POST' }) + } catch {} + } +} + +export class StorageNode { + /** @param {{ http: import('http'), claimsService: API.ClaimsClientConfig } & import('@ucanto/interface').PrincipalResolver} config */ + static async activate({ http, claimsService, resolveDIDKey }) { + const id = await ed25519.generate() + /** @type {URL} */ + let baseURL + + const content = new Map() + const contentStore = { + /** @param {API.MultihashDigest} digest */ + has: async (digest) => content.has(contentKey(digest)), + /** @param {API.MultihashDigest} digest */ + get: async (digest) => content.get(contentKey(digest)), + /** + * @param {API.MultihashDigest} digest + * @param {Uint8Array} bytes + */ + set: async (digest, bytes) => { + content.set(contentKey(digest), bytes) + }, + } + + const allocations = new Set() + const allocationStore = { + /** @param {API.MultihashDigest} digest */ + has: async (digest) => allocations.has(contentKey(digest)), + /** @param {API.MultihashDigest} digest */ + add: async (digest) => { + allocations.add(contentKey(digest)) + }, + } + + const server = Server.create({ + id, + codec: CAR.inbound, + service: createService({ + baseURL: () => baseURL, + claimsService, + contentStore, + allocationStore, + }), + resolveDIDKey, + validateAuthorization: () => ({ ok: {} }), + }) + + const httpServer = http.createServer(async (request, response) => { + try { + const { pathname } = new URL(request.url ?? '/', baseURL) + if (request.method === 'POST') { + const chunks = [] + for await (const chunk of request) { + chunks.push(chunk) + } + + const { status, headers, body } = await server.request({ + headers: Object.fromEntries( + Object.entries(request.headers).map(([k, v]) => [k, String(v)]) + ), + body: new Uint8Array(await new Blob(chunks).arrayBuffer()), + }) + + response.writeHead(status ?? 200, headers) + response.write(body) + } else if (request.method === 'PUT') { + const length = parseInt(request.headers['content-length'] ?? '0') + const buffer = new Uint8Array(length) + let offset = 0 + for await (const chunk of request) { + buffer.set(chunk, offset) + offset += chunk.length + } + const digest = await sha256.digest(buffer) + const checksum = base64pad.baseEncode(digest.digest) + + if (checksum !== request.headers['x-amz-checksum-sha256']) { + response.writeHead(400, `checksum mismatch`) + } else { + await contentStore.set(digest, buffer) + response.writeHead(200) + } + } else if (request.method === 'GET') { + const data = await contentStore.get(contentDigest(pathname)) + if (data) { + response.writeHead(200) + response.write(data) + } else { + response.writeHead(404) + } + } else { + response.writeHead(405) + } + } catch (err) { + console.error(err) + response.writeHead(500) + } + + response.end() + // otherwise it keep connection lingering + response.destroy() + }) + await new Promise((resolve) => httpServer.listen(resolve)) + + // @ts-ignore - this is actually what it returns on http + const { port } = httpServer.address() + baseURL = new URL(`http://127.0.0.1:${port}`) + const channel = HTTP.open({ url: baseURL, method: 'POST' }) + const connection = connect({ id, codec: CAR.outbound, channel }) + + return new StorageNode({ id, connection, server: httpServer }) + } + + /** + * @param {{ + * id: API.Signer + * connection: import('@ucanto/interface').ConnectionView + * server: import('http').Server + * }} config + */ + constructor({ id, connection, server }) { + this.id = id + this.connection = connection + this.server = server + } + + async deactivate() { + await new Promise((resolve, reject) => { + this.server.closeAllConnections() + this.server.close((error) => { + if (error) { + reject(error) + } else { + resolve(undefined) + } + }) + }) + } +} + +/** + * @param {API.ClaimsClientContext} ctx + * @param {{ space: Uint8Array, digest: API.MultihashDigest, location: API.URI }} params + */ +const publishLocationCommitment = async (ctx, { digest, location }) => { + const { invocationConfig, connection } = ctx.claimsService + const { issuer, audience, with: resource, proofs } = invocationConfig + return await Assert.location + .invoke({ + issuer, + audience, + with: resource, + nb: { content: { digest: digest.bytes }, location: [location] }, + expiration: Infinity, + proofs, + }) + .execute(connection) +} diff --git a/packages/upload-api/test/handlers/access/authorize.js b/packages/upload-api/test/handlers/access/authorize.js index 0293c8df3..9e75412eb 100644 --- a/packages/upload-api/test/handlers/access/authorize.js +++ b/packages/upload-api/test/handlers/access/authorize.js @@ -1,13 +1,13 @@ import * as API from '../../types.js' import { Absentee } from '@ucanto/principal' import { delegate, parseLink } from '@ucanto/core' -import { Access, Space } from '@web3-storage/capabilities' +import { Access, Space } from '@storacha/capabilities' import { alice, bob, provisionProvider } from '../../helpers/utils.js' -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' import { stringToDelegation, bytesToDelegations, -} from '@web3-storage/access/encoding' +} from '@storacha/access/encoding' import { authorizeFromUrl } from '../../../src/validate.js' /** @@ -36,7 +36,7 @@ export const test = { const url = new URL(email.url) const encoded = - /** @type {import('@web3-storage/access/types').EncodedDelegation<[import('@web3-storage/capabilities/types').AccessConfirm]>} */ ( + /** @type {import('@storacha/access/types').EncodedDelegation<[import('@storacha/capabilities/types').AccessConfirm]>} */ ( url.searchParams.get('ucan') ) const delegation = stringToDelegation(encoded) diff --git a/packages/upload-api/test/handlers/access/claim.js b/packages/upload-api/test/handlers/access/claim.js index c4148ef23..c1e3e9d08 100644 --- a/packages/upload-api/test/handlers/access/claim.js +++ b/packages/upload-api/test/handlers/access/claim.js @@ -1,6 +1,6 @@ import * as API from '../../types.js' import { Absentee } from '@ucanto/principal' -import { Access } from '@web3-storage/capabilities' +import { Access } from '@storacha/capabilities' import { alice, bob } from '../../helpers/utils.js' /** diff --git a/packages/upload-api/test/handlers/access/delegate.js b/packages/upload-api/test/handlers/access/delegate.js index 8df088fc9..0baae31a3 100644 --- a/packages/upload-api/test/handlers/access/delegate.js +++ b/packages/upload-api/test/handlers/access/delegate.js @@ -1,7 +1,7 @@ import * as API from '../../types.js' import { Absentee } from '@ucanto/principal' import * as Server from '@ucanto/server' -import { Access } from '@web3-storage/capabilities' +import { Access } from '@storacha/capabilities' import { alice, bob, mallory, provisionProvider } from '../../helpers/utils.js' import * as delegationsResponse from '../../../src/utils/delegations-response.js' diff --git a/packages/upload-api/test/handlers/admin/store/inspect.js b/packages/upload-api/test/handlers/admin/store/inspect.js deleted file mode 100644 index decb082a2..000000000 --- a/packages/upload-api/test/handlers/admin/store/inspect.js +++ /dev/null @@ -1,66 +0,0 @@ -import * as API from '../../../types.js' -import { alice, registerSpace } from '../../../util.js' -import { createServer, connect } from '../../../../src/lib.js' - -import { delegate } from '@ucanto/core' -import * as CAR from '@ucanto/transport/car' -import { Admin, Store } from '@web3-storage/capabilities' - -/** - * @type {API.Tests} - */ -export const test = { - 'admin/store/inspect returns information about an uploaded CID': async ( - assert, - context - ) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - const size = data.byteLength - - const storeAdd = await Store.add - .invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { link, size }, - proofs: [proof], - }) - .execute(connection) - - assert.ok(storeAdd.out.ok) - - const service = context.service - const adminStoreInspect = await Admin.store.inspect - .invoke({ - issuer: alice, - audience: connection.id, - with: service.did(), - nb: { link }, - proofs: [ - await delegate({ - issuer: service, - audience: alice, - capabilities: [{ with: service.did(), can: 'admin/store/inspect' }], - }), - ], - }) - .execute(connection) - - assert.ok( - adminStoreInspect.out.ok, - `failed to get shard: ${adminStoreInspect.out.error?.message}` - ) - assert.equal(adminStoreInspect.out.ok?.spaces[0].did, spaceDid) - assert.equal( - typeof adminStoreInspect.out.ok?.spaces[0].insertedAt, - 'string' - ) - }, -} diff --git a/packages/upload-api/test/handlers/admin/store/inspect.spec.js b/packages/upload-api/test/handlers/admin/store/inspect.spec.js deleted file mode 100644 index 7a786c0c7..000000000 --- a/packages/upload-api/test/handlers/admin/store/inspect.spec.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as Inspect from './inspect.js' -import { test } from '../../../test.js' -test({ 'admin/store/inspect': Inspect.test }) diff --git a/packages/upload-api/test/handlers/admin/upload/inspect.js b/packages/upload-api/test/handlers/admin/upload/inspect.js index fbd59fc71..50bd8e421 100644 --- a/packages/upload-api/test/handlers/admin/upload/inspect.js +++ b/packages/upload-api/test/handlers/admin/upload/inspect.js @@ -3,7 +3,7 @@ import { alice, registerSpace, randomCAR } from '../../../util.js' import { createServer, connect } from '../../../../src/lib.js' import { delegate } from '@ucanto/core' -import { Admin, Upload } from '@web3-storage/capabilities' +import { Admin, Upload } from '@storacha/capabilities' /** * @type {API.Tests} diff --git a/packages/upload-api/test/handlers/blob.js b/packages/upload-api/test/handlers/blob.js index 10595937e..f0ecb1b4a 100644 --- a/packages/upload-api/test/handlers/blob.js +++ b/packages/upload-api/test/handlers/blob.js @@ -2,13 +2,12 @@ import * as API from '../../src/types.js' import { sha256 } from 'multiformats/hashes/sha2' import { ed25519 } from '@ucanto/principal' import { Receipt } from '@ucanto/core' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' - +import * as BlobCapabilities from '@storacha/capabilities/space/blob' import { createServer, connect } from '../../src/lib.js' import { alice, registerSpace } from '../util.js' -import { BlobSizeOutsideOfSupportedRangeName } from '../../src/blob/lib.js' import { createConcludeInvocation } from '../../src/ucan/conclude.js' -import { parseBlobAddReceiptNext } from '../helpers/blob.js' +import { parseBlobAddReceiptNext, uploadBlob } from '../helpers/blob.js' +import { BlobSizeLimitExceededError } from '../../src/blob.js' /** * @type {API.Tests} @@ -57,7 +56,7 @@ export const test = { blobAdd.out.ok.site['ucan/await'][1], next.accept.task.cid ) - assert.equal(blobAdd.fx.fork.length, 4) + assert.equal(blobAdd.fx.fork.length, 7) // validate receipt next assert.ok(next.allocate.task) @@ -114,6 +113,9 @@ export const test = { }, }, proofs: [proof], + // Note: we have to set an expiration, or the default expiration value + // will be set when the invocation is executed and the UCAN issued. + expiration: Math.floor(Date.now() / 1000) + 10, }) // Invoke `blob/add` for the first time const firstBlobAdd = await invocation.execute(connection) @@ -148,7 +150,9 @@ export const test = { const firstAllocateTaskLink = firstNext.allocate.task.link() const secondAllocateTaskLink = secondNext.allocate.task.link() - if (firstAllocateTaskLink.toString() !== secondAllocateTaskLink.toString()) { + if ( + firstAllocateTaskLink.toString() !== secondAllocateTaskLink.toString() + ) { console.error('allocate receipts not equal:') console.error(firstNext.allocate.receipt) console.error(secondNext.allocate.receipt) @@ -217,7 +221,7 @@ export const test = { assert.ok(firstNext.accept.task, 'accept task was dispatched') assert.ok(!firstNext.accept.receipt, 'accept receipt was not received') - /** @type {import('@web3-storage/capabilities/types').BlobAddress} */ + /** @type {import('@storacha/capabilities/types').BlobAddress} */ // @ts-expect-error receipt type is unknown const address = firstNext.allocate.receipt.out.ok.address @@ -387,7 +391,7 @@ export const test = { assert.ok(workflow.accept.task, 'accept task was dispatched') assert.ok(!workflow.accept.receipt, 'accept receipt was not received') - /** @type {import('@web3-storage/capabilities/types').BlobAddress} */ + /** @type {import('@storacha/capabilities/types').BlobAddress} */ // @ts-expect-error receipt type is unknown const address = workflow.allocate.receipt.out.ok.address @@ -409,7 +413,7 @@ export const test = { ) const ucanConclude = await httpPutConcludeInvocation.execute(connection) if (!ucanConclude.out.ok) { - throw new Error('invocation failed', { cause: ucanConclude.out }) + throw new Error('invocation failed', { cause: ucanConclude.out.error }) } const accept = await context.agentStore.receipts.get( @@ -464,7 +468,7 @@ export const test = { assert.ok(work.allocate.receipt.out.error, 'allocation has failed') assert.equal( work.allocate.receipt.out.error?.name, - BlobSizeOutsideOfSupportedRangeName, + BlobSizeLimitExceededError.name, 'allocation failed with BlobSizeOutsideOfSupportedRange error' ) assert.ok(work.put.task, 'put task was scheduled') @@ -482,8 +486,7 @@ export const test = { // prepare data const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes + const digest = await sha256.digest(data) const size = data.byteLength // create service connection @@ -492,24 +495,16 @@ export const test = { channel: createServer(context), }) - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, + await uploadBlob( + { + issuer: alice, + audience: context.id, + with: spaceDid, + proofs: [proof], + connection, }, - proofs: [proof], - }) - // Invoke `blob/add` to allocate content - const blobAdd = await blobAddInvocation.execute(connection) - if (!blobAdd.out.ok) { - throw new Error('invocation failed', { cause: blobAdd.out.error }) - } + { digest, bytes: data } + ) // invoke `blob/remove` const blobRemoveInvocation = BlobCapabilities.remove.invoke({ @@ -517,7 +512,7 @@ export const test = { audience: context.id, with: spaceDid, nb: { - digest, + digest: digest.bytes, }, proofs: [proof], }) @@ -595,31 +590,17 @@ export const test = { new Uint8Array([11, 22, 34, 44, 55]), new Uint8Array([22, 34, 44, 55, 66]), ] - const receipts = [] for (const datum of data) { - const multihash = await sha256.digest(datum) - const digest = multihash.bytes - const size = datum.byteLength - const blobAdd = await BlobCapabilities.add - .invoke({ + await uploadBlob( + { issuer: alice, - audience: connection.id, + audience: context.id, with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, proofs: [proof], - }) - .execute(connection) - - if (blobAdd.out.error) { - throw new Error('invocation failed', { cause: blobAdd }) - } - - receipts.push(blobAdd) + connection, + }, + { digest: await sha256.digest(datum), bytes: datum } + ) } const blobList = await BlobCapabilities.list @@ -635,7 +616,7 @@ export const test = { if (blobList.out.error) { throw new Error('invocation failed', { cause: blobList }) } - assert.equal(blobList.out.ok.size, receipts.length) + assert.equal(blobList.out.ok.size, data.length) // list order last-in-first-out const listReverse = await Promise.all( data @@ -660,27 +641,16 @@ export const test = { ] for (const datum of data) { - const multihash = await sha256.digest(datum) - const digest = multihash.bytes - const size = datum.byteLength - const blobAdd = await BlobCapabilities.add - .invoke({ + await uploadBlob( + { issuer: alice, - audience: connection.id, + audience: context.id, with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, proofs: [proof], - }) - .execute(connection) - - if (blobAdd.out.error) { - throw new Error('invocation failed', { cause: blobAdd }) - } + connection, + }, + { digest: await sha256.digest(datum), bytes: datum } + ) } // Get list with page size 1 (two pages) diff --git a/packages/upload-api/test/handlers/index.js b/packages/upload-api/test/handlers/index.js index d74ff04d7..9e0e73680 100644 --- a/packages/upload-api/test/handlers/index.js +++ b/packages/upload-api/test/handlers/index.js @@ -1,7 +1,7 @@ import * as API from '../../src/types.js' import { CAR } from '@ucanto/core' -import * as IndexCapabilities from '@web3-storage/capabilities/index' -import { fromShardArchives } from '@web3-storage/blob-index/util' +import * as IndexCapabilities from '@storacha/capabilities/space/index' +import { fromShardArchives } from '@storacha/blob-index/util' import { createServer, connect } from '../../src/lib.js' import { alice, randomCAR, registerSpace } from '../util.js' import { uploadBlob } from '../helpers/blob.js' @@ -9,76 +9,6 @@ import * as Result from '../helpers/result.js' /** @type {API.Tests} */ export const test = { - 'index/add should publish index to IPNI service': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const contentCAR = await randomCAR(32) - const contentCARBytes = new Uint8Array(await contentCAR.arrayBuffer()) - - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // upload the content CAR to the space - await uploadBlob( - context, - { - connection, - issuer: alice, - audience: context.id, - with: spaceDid, - proofs: [proof], - }, - { - cid: contentCAR.cid, - bytes: contentCARBytes, - } - ) - - const index = await fromShardArchives(contentCAR.roots[0], [ - contentCARBytes, - ]) - const indexCAR = Result.unwrap(await index.archive()) - const indexLink = await CAR.link(indexCAR) - - // upload the index CAR to the space - await uploadBlob( - context, - { - connection, - issuer: alice, - audience: context.id, - with: spaceDid, - proofs: [proof], - }, - { - cid: indexLink, - bytes: indexCAR, - } - ) - - const indexAdd = IndexCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { index: indexLink }, - proofs: [proof], - }) - const receipt = await indexAdd.execute(connection) - Result.try(receipt.out) - - // ensure a result exists for the content root - assert.ok( - Result.unwrap(await context.ipniService.query(index.content.multihash)) - ) - - for (const shard of index.shards.values()) { - for (const slice of shard.entries()) { - // ensure a result exists for each multihash in the index - assert.ok(Result.unwrap(await context.ipniService.query(slice[0]))) - } - } - }, 'index/add should fail if index is not stored in agent space': async ( assert, context @@ -94,7 +24,6 @@ export const test = { // upload the content CAR to the space await uploadBlob( - context, { connection, issuer: alice, @@ -103,7 +32,7 @@ export const test = { proofs: [proof], }, { - cid: contentCAR.cid, + digest: contentCAR.cid.multihash, bytes: contentCARBytes, } ) @@ -146,7 +75,6 @@ export const test = { // upload the index CAR to the space await uploadBlob( - context, { connection, issuer: alice, @@ -155,7 +83,7 @@ export const test = { proofs: [proof], }, { - cid: indexLink, + digest: indexLink.multihash, bytes: indexCAR, } ) @@ -183,7 +111,6 @@ export const test = { // upload the content CAR to the space await uploadBlob( - context, { connection, issuer: alice, @@ -192,7 +119,7 @@ export const test = { proofs: [proof], }, { - cid: contentCAR.cid, + digest: contentCAR.cid.multihash, bytes: contentCARBytes, } ) @@ -205,7 +132,6 @@ export const test = { // upload the index CAR to the space await uploadBlob( - context, { connection, issuer: alice, @@ -214,7 +140,7 @@ export const test = { proofs: [proof], }, { - cid: indexLink, + digest: indexLink.multihash, bytes: indexCAR, } ) diff --git a/packages/upload-api/test/handlers/plan.js b/packages/upload-api/test/handlers/plan.js index a718fb4a5..a18c197ec 100644 --- a/packages/upload-api/test/handlers/plan.js +++ b/packages/upload-api/test/handlers/plan.js @@ -1,7 +1,7 @@ import * as API from '../../src/types.js' import { createServer, connect } from '../../src/lib.js' import { alice } from '../util.js' -import { Plan } from '@web3-storage/capabilities' +import { Plan } from '@storacha/capabilities' import { createAuthorization } from '../helpers/utils.js' import { Absentee } from '@ucanto/principal' @@ -12,7 +12,7 @@ export const test = { 'an account can get plan information': async (assert, context) => { const account = 'did:mailto:example.com:alice' const billingID = 'stripe:abc123' - const product = 'did:web:test.web3.storage' + const product = 'did:web:test.upload.storacha.network' await context.plansStorage.initialize(account, billingID, product) const connection = connect({ id: context.id, diff --git a/packages/upload-api/test/handlers/provider-add.spec.js b/packages/upload-api/test/handlers/provider-add.spec.js index b348c9d32..f0a3ba58b 100644 --- a/packages/upload-api/test/handlers/provider-add.spec.js +++ b/packages/upload-api/test/handlers/provider-add.spec.js @@ -4,7 +4,7 @@ import * as ucanto from '@ucanto/core' import * as API from '../../src/types.js' import * as Types from '../types.js' import { cleanupContext, createContext } from '../helpers/context.js' -import { Access, Provider, Consumer } from '@web3-storage/capabilities' +import { Access, Provider, Consumer } from '@storacha/capabilities' import * as delegationsResponse from '../../src/utils/delegations-response.js' import { NON_STANDARD } from '@ipld/dag-ucan/signature' import { createAuthorization } from '../helpers/utils.js' @@ -176,7 +176,7 @@ describe(`provider/add`, () => { it('add providers set in env', async () => { const { space, agent, account, ...context } = await setup({ - providers: ['did:web:nft.storage', 'did:web:web3.storage'], + providers: ['did:web:nft.storage', 'did:web:storacha.network'], }) const { service } = context try { @@ -203,7 +203,7 @@ describe(`provider/add`, () => { audience: service, with: account.did(), nb: { - provider: 'did:web:web3.storage', + provider: 'did:web:storacha.network', consumer: w3space.did(), }, proofs, @@ -218,7 +218,7 @@ describe(`provider/add`, () => { it('provider/add can not add two diff providers to the same space', async () => { const { space, agent, account, ...context } = await setup({ - providers: ['did:web:nft.storage', 'did:web:web3.storage'], + providers: ['did:web:nft.storage', 'did:web:storacha.network'], }) const { service } = context @@ -245,7 +245,7 @@ describe(`provider/add`, () => { audience: service, with: account.did(), nb: { - provider: 'did:web:web3.storage', + provider: 'did:web:storacha.network', consumer: space.did(), }, proofs, @@ -273,7 +273,7 @@ describe(`provider/add`, () => { audience: service, with: account.did(), nb: { - provider: 'did:web:web3.storage', + provider: 'did:web:storacha.network', consumer: space.did(), }, proofs, @@ -318,7 +318,7 @@ const setup = async (options = {}) => { * @param {API.Signer>} options.deviceA * @param {API.Signer} options.space * @param {API.Principal>} options.accountA - * @param {API.Signer>} options.service - web3.storage service + * @param {API.Signer>} options.service - storacha.network service * @param {API.ConnectionView} options.conn * @param {API.AccessServiceContext} options.context * @param {API.DebugEmail} options.emails diff --git a/packages/upload-api/test/handlers/rate-limit/add.js b/packages/upload-api/test/handlers/rate-limit/add.js index 0e2dad60a..998d28fa2 100644 --- a/packages/upload-api/test/handlers/rate-limit/add.js +++ b/packages/upload-api/test/handlers/rate-limit/add.js @@ -2,9 +2,9 @@ import * as API from '../../types.js' import { alice, bob } from '../../helpers/utils.js' import { Absentee } from '@ucanto/principal' import { delegate } from '@ucanto/core' -import { Access, RateLimit, Store } from '@web3-storage/capabilities' +import { Access, RateLimit, SpaceBlob } from '@storacha/capabilities' import * as CAR from '@ucanto/transport/car' -import * as DidMailto from '@web3-storage/did-mailto' +import * as DidMailto from '@storacha/did-mailto' /** * @type {API.Tests} @@ -112,17 +112,17 @@ export const test = { const data = new Uint8Array([11, 22, 34, 44, 55]) const link = await CAR.codec.link(data) const size = data.byteLength - const storeResult = await Store.add + const storeResult = await SpaceBlob.add .invoke({ issuer: agent, audience: service, with: space.did(), - nb: { link, size }, + nb: { blob: { digest: link.multihash.bytes, size } }, proofs: [ await delegate({ issuer: space, audience: agent, - capabilities: [{ with: space.did(), can: 'store/add' }], + capabilities: [{ with: space.did(), can: SpaceBlob.add.can }], }), ], }) diff --git a/packages/upload-api/test/handlers/rate-limit/list.js b/packages/upload-api/test/handlers/rate-limit/list.js index 75b81f129..920b2ac26 100644 --- a/packages/upload-api/test/handlers/rate-limit/list.js +++ b/packages/upload-api/test/handlers/rate-limit/list.js @@ -2,7 +2,7 @@ import * as API from '../../types.js' import { alice, bob } from '../../helpers/utils.js' import { Absentee } from '@ucanto/principal' import { delegate } from '@ucanto/core' -import { RateLimit } from '@web3-storage/capabilities' +import { RateLimit } from '@storacha/capabilities' /** * @type {API.Tests} diff --git a/packages/upload-api/test/handlers/rate-limit/remove.js b/packages/upload-api/test/handlers/rate-limit/remove.js index cbe42564c..f29baa3ff 100644 --- a/packages/upload-api/test/handlers/rate-limit/remove.js +++ b/packages/upload-api/test/handlers/rate-limit/remove.js @@ -2,7 +2,7 @@ import * as API from '../../types.js' import { alice, bob } from '../../helpers/utils.js' import { Absentee } from '@ucanto/principal' import { delegate } from '@ucanto/core' -import { RateLimit } from '@web3-storage/capabilities' +import { RateLimit } from '@storacha/capabilities' /** * @type {API.Tests} diff --git a/packages/upload-api/test/handlers/space-info.spec.js b/packages/upload-api/test/handlers/space-info.spec.js index ed22537d1..8ae08f1bb 100644 --- a/packages/upload-api/test/handlers/space-info.spec.js +++ b/packages/upload-api/test/handlers/space-info.spec.js @@ -1,11 +1,11 @@ -import * as Space from '@web3-storage/capabilities/space' +import * as Space from '@storacha/capabilities/space' import assert from 'assert' import { cleanupContext, createContext } from '../helpers/context.js' import { createSpace } from '../helpers/utils.js' import { parseLink } from '@ucanto/core' import * as principal from '@ucanto/principal' -import * as Store from '@web3-storage/capabilities/store' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Store from '@storacha/capabilities/store' +import * as Upload from '@storacha/capabilities/upload' // @ts-ignore import isSubset from 'is-subset' diff --git a/packages/upload-api/test/handlers/store.js b/packages/upload-api/test/handlers/store.js deleted file mode 100644 index 37a8c5234..000000000 --- a/packages/upload-api/test/handlers/store.js +++ /dev/null @@ -1,872 +0,0 @@ -import { createServer, connect } from '../../src/lib.js' -import * as API from '../../src/types.js' -import * as CAR from '@ucanto/transport/car' -import { base64pad } from 'multiformats/bases/base64' -import * as Raw from 'multiformats/codecs/raw' -import { sha256 } from 'multiformats/hashes/sha2' -import * as Link from 'multiformats/link' -import * as StoreCapabilities from '@web3-storage/capabilities/store' -import { invoke } from '@ucanto/core' -import { alice, bob, createSpace, registerSpace } from '../util.js' -import { Absentee } from '@ucanto/principal' -import { provisionProvider } from '../helpers/utils.js' -import * as Result from '../helpers/result.js' - -/** - * @type {API.Tests} - */ -export const test = { - 'store/add returns signed url for uploading': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - const size = data.byteLength - - const invocation = StoreCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { link, size }, - proofs: [proof], - }) - - // invoke a store/add with proof - const storeAdd = await invocation.execute(connection) - - if (!storeAdd.out.ok) { - throw new Error('invocation failed', { cause: storeAdd }) - } - if (storeAdd.out.ok.status !== 'upload') { - throw new Error(`unexpected status: ${storeAdd.out.ok.status}`) - } - - assert.equal(storeAdd.out.ok.with, spaceDid) - assert.deepEqual(storeAdd.out.ok.link.toString(), link.toString()) - - assert.equal(storeAdd.out.ok.headers?.['content-length'], String(size)) - assert.deepEqual( - storeAdd.out.ok.headers?.['x-amz-checksum-sha256'], - base64pad.baseEncode(link.multihash.digest) - ) - - const url = storeAdd.out.ok.url && new URL(storeAdd.out.ok.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - const signedHeaders = url.searchParams.get('X-Amz-SignedHeaders') - - assert.equal( - signedHeaders, - 'content-length;host;x-amz-checksum-sha256', - 'content-length and checksum must be part of the signature' - ) - - // May have bucket name at start of path - assert.equal(url.pathname.endsWith(`/${link}/${link}.car`), true) - - const goodPut = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: storeAdd.out.ok.headers, - }) - - assert.equal(goodPut.status, 200, await goodPut.text()) - - const item = Result.unwrap(await context.storeTable.get(spaceDid, link)) - - assert.deepEqual( - { - link: item.link.toString(), - size: item.size, - }, - { - link: link.toString(), - size: data.byteLength, - } - ) - - assert.equal( - Date.now() - new Date(item?.insertedAt).getTime() < 60_000, - true - ) - - const { spaces } = Result.unwrap(await context.storeTable.inspect(link)) - assert.equal(spaces.length, 1) - assert.equal(spaces[0].did, spaceDid) - }, - - 'store/add should allow add the same content to be stored in multiple spaces': - async (assert, context) => { - const { proof: aliceProof, spaceDid: aliceSpaceDid } = - await registerSpace(alice, context) - const { proof: bobProof, spaceDid: bobSpaceDid } = await registerSpace( - bob, - context, - 'bob' - ) - - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - const size = data.byteLength - - const aliceStoreAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: context.id, - with: aliceSpaceDid, - nb: { link, size }, - proofs: [aliceProof], - }) - .execute(connection) - - assert.ok( - aliceStoreAdd.out.ok, - `Alice failed to store ${link.toString()}` - ) - - const bobStoreAdd = await StoreCapabilities.add - .invoke({ - issuer: bob, - audience: context.id, - with: bobSpaceDid, - nb: { link, size }, - proofs: [bobProof], - }) - .execute(connection) - - assert.ok(bobStoreAdd.out.ok, `Bob failed to store ${link.toString()}`) - - const { spaces } = Result.unwrap(await context.storeTable.inspect(link)) - assert.equal(spaces.length, 2) - const spaceDids = spaces.map((space) => space.did) - assert.ok(spaceDids.includes(aliceSpaceDid)) - assert.ok(spaceDids.includes(bobSpaceDid)) - }, - - 'store/add should create a presigned url that can only PUT a payload with the right length': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const longer = new Uint8Array([11, 22, 34, 44, 55, 66]) - const link = await CAR.codec.link(data) - const size = data.byteLength - - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { link, size }, - proofs: [proof], - }) - .execute(connection) - - if (!storeAdd.out.ok) { - throw new Error('invocation failed', { cause: storeAdd }) - } - if (storeAdd.out.ok.status !== 'upload') { - throw new Error(`unexpected status: ${storeAdd.out.ok.status}`) - } - - const url = new URL(storeAdd.out.ok.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - - const contentLengthFailSignature = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: longer, - headers: { - ...storeAdd.out.ok.headers, - 'content-length': longer.byteLength.toString(10), - }, - }) - - assert.equal( - contentLengthFailSignature.status >= 400, - true, - 'should fail to upload as content-length differs from that used to sign the url' - ) - }, - - 'store/add should create a presigned url that can only PUT the exact bytes we signed for': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const other = new Uint8Array([10, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - const size = data.byteLength - - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { link, size }, - proofs: [proof], - }) - .execute(connection) - - if (!storeAdd.out.ok) { - throw new Error('invocation failed', { cause: storeAdd }) - } - if (storeAdd.out.ok.status !== 'upload') { - throw new Error(`unexpected status: ${storeAdd.out.ok.status}`) - } - - const url = new URL(storeAdd.out.ok.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - - const failChecksum = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: other, - headers: storeAdd.out.ok.headers, - }) - - assert.equal( - failChecksum.status, - 400, - 'should fail to upload any other data.' - ) - }, - - 'store/add returns done if already uploaded': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - - const { url, headers } = await context.carStoreBucket.createUploadUrl( - link, - data.length - ) - - // simulate an already stored CAR - const put = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: data, - headers, - }) - assert.equal(put.ok, true, 'should be able to upload to presigned url') - - const storeAddInvocation = StoreCapabilities.add.invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size: data.byteLength }, - proofs: [proof], - }) - - const storeAdd = await storeAddInvocation.execute(connection) - - if (!storeAdd.out.ok) { - throw new Error('invocation failed', { cause: storeAdd }) - } - - assert.equal(storeAdd.out.ok.status, 'done') - assert.equal(storeAdd.out.ok.allocated, 5) - assert.equal(storeAdd.out.ok.with, spaceDid) - assert.deepEqual(storeAdd.out.ok.link.toString(), link.toString()) - // @ts-expect-error making sure it's not an upload status - assert.equal(storeAdd.out.ok.url == null, true) - - const item = Result.unwrap(await context.storeTable.get(spaceDid, link)) - - assert.deepEqual( - { - link: item.link.toString(), - size: item.size, - }, - { - link: link.toString(), - size: data.byteLength, - } - ) - - assert.equal( - Date.now() - new Date(item.insertedAt).getTime() < 60_000, - true - ) - }, - - 'store/add returns allocated: 0 if already added to space': async ( - assert, - context - ) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - - const { url, headers } = await context.carStoreBucket.createUploadUrl( - link, - data.length - ) - - // simulate an already stored CAR - const put = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: data, - headers, - }) - assert.equal(put.ok, true, 'should be able to upload to presigned url') - - const inv0 = StoreCapabilities.add.invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size: data.byteLength }, - nonce: '0', - proofs: [proof], - }) - - const r0 = await inv0.execute(connection) - - assert.equal(r0.out.ok?.status, 'done') - assert.equal(r0.out.ok?.allocated, 5) - assert.equal(r0.out.ok?.with, spaceDid) - - const inv1 = StoreCapabilities.add.invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size: data.byteLength }, - nonce: '1', - proofs: [proof], - }) - - const r1 = await inv1.execute(connection) - - assert.equal(r1.out.ok?.status, 'done') - assert.equal(r1.out.ok?.allocated, 0) - assert.equal(r1.out.ok?.with, spaceDid) - }, - - 'store/add disallowed if invocation fails access verification': async ( - assert, - context - ) => { - const { proof, space, spaceDid } = await createSpace(alice) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - - // invoke a store/add with proof - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size: data.byteLength }, - proofs: [proof], - }) - .execute(connection) - - assert.ok(storeAdd.out.error) - assert.equal(storeAdd.out.error?.message.includes('no storage'), true) - - // Register space and retry - const account = Absentee.from({ id: 'did:mailto:test.web3.storage:alice' }) - const providerAdd = await provisionProvider({ - service: /** @type {API.Signer>} */ (context.signer), - agent: alice, - space, - account, - connection, - }) - assert.ok(providerAdd.out.ok) - - const retryStoreAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size: data.byteLength }, - proofs: [proof], - nonce: 'retry', - }) - .execute(connection) - - assert.equal(retryStoreAdd.out.error, undefined) - }, - - 'store/add fails when size too large to PUT': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - const size = context.maxUploadSize + 1 - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link, size }, - proofs: [proof], - }) - .execute(connection) - - assert.ok(storeAdd.out.error) - assert.equal( - storeAdd.out.error?.message.startsWith('Maximum size exceeded:'), - true - ) - }, - - 'store/add fails with non-car link': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - /** @type {API.Link} */ - const link = Link.create(Raw.code, await sha256.digest(data)) - const size = context.maxUploadSize + 1 - - // Throws because invocation builder expects CAR link - try { - StoreCapabilities.add.invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { - link, - size, - }, - proofs: [proof], - }) - assert.ok(false, 'should have throw exception') - } catch (error) { - assert.ok(String(error).match(/0x202 codec/)) - } - - // Going around client validation will still fail because server handler - // expects CAR link. - const invocation = await invoke({ - issuer: alice, - audience: connection.id, - capability: { - can: 'store/add', - with: spaceDid, - nb: { - link, - size, - }, - }, - - proofs: [proof], - }).delegate() - - const [storeAdd] = await connection.execute(invocation) - assert.ok(storeAdd.out.error) - assert.ok(storeAdd.out.error?.message.match('0x202 codec')) - }, - - 'store/remove fails for non existent link': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const link = await CAR.codec.link(data) - - const storeRemove = await StoreCapabilities.remove - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link }, - proofs: [proof], - }) - .execute(connection) - - assert.equal(storeRemove.out.error?.name, 'StoreItemNotFound') - }, - - 'store/list does not fail for empty list': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const storeList = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: {}, - }) - .execute(connection) - - assert.deepEqual(storeList.out.ok, { results: [], size: 0 }) - }, - - 'store/list returns items previously stored by the user': async ( - assert, - context - ) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = [ - new Uint8Array([11, 22, 34, 44, 55]), - new Uint8Array([22, 34, 44, 55, 66]), - ] - const links = [] - for (const datum of data) { - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link: await CAR.codec.link(datum), size: datum.byteLength }, - proofs: [proof], - }) - .execute(connection) - - if (storeAdd.out.error) { - throw new Error('invocation failed', { cause: storeAdd }) - } - - assert.equal(storeAdd.out.ok.status, 'upload') - links.push(storeAdd.out.ok.link) - } - - const storeList = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: {}, - }) - .execute(connection) - - if (storeList.out.error) { - throw new Error('invocation failed', { cause: storeList }) - } - - assert.equal(storeList.out.ok.size, links.length) - - // list order last-in-first-out - assert.deepEqual( - storeList.out.ok.results.map(({ link }) => ({ link, size: 5 })), - links.reverse().map((link) => ({ link, size: 5 })) - ) - }, - - 'store/list can be paginated with custom size': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = [ - new Uint8Array([11, 22, 34, 44, 55]), - new Uint8Array([22, 34, 44, 55, 66]), - ] - const links = [] - - for (const datum of data) { - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link: await CAR.codec.link(datum), size: datum.byteLength }, - proofs: [proof], - }) - .execute(connection) - if (storeAdd.out.error) { - throw new Error('invocation failed', { cause: storeAdd }) - } - - links.push(storeAdd.out.ok.link) - } - - // Get list with page size 1 (two pages) - const size = 1 - const listPages = [] - /** @type {string} */ - let cursor = '' - - do { - const storeList = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - size, - ...(cursor ? { cursor } : {}), - }, - }) - .execute(connection) - - if (storeList.out.error) { - throw new Error('invocation failed', { cause: storeList }) - } - - // Add page if it has size - storeList.out.ok.size > 0 && listPages.push(storeList.out.ok.results) - - if (storeList.out.ok.after) { - cursor = storeList.out.ok.after - } else { - break - } - } while (cursor) - - assert.equal( - listPages.length, - data.length, - 'has number of pages of added CARs' - ) - - // Inspect content - const storeList = listPages.flat() - assert.deepEqual( - // list order last-in-first-out - storeList.map(({ link }) => ({ link, size: 5 })), - links.reverse().map((link) => ({ link, size: 5 })) - ) - }, - - 'store/list can page backwards': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = [ - new Uint8Array([11, 22, 33, 44, 55]), - new Uint8Array([22, 33, 44, 55, 66]), - new Uint8Array([33, 44, 55, 66, 77]), - new Uint8Array([44, 55, 66, 77, 88]), - new Uint8Array([55, 66, 77, 88, 99]), - new Uint8Array([66, 77, 88, 99, 11]), - ] - const links = [] - - for (const datum of data) { - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link: await CAR.codec.link(datum), size: datum.byteLength }, - proofs: [proof], - }) - .execute(connection) - if (storeAdd.out.error) { - throw new Error('invocation failed', { cause: storeAdd }) - } - - links.push(storeAdd.out.ok.link) - } - - const size = 3 - - const listResponse = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - size, - }, - }) - .execute(connection) - if (listResponse.out.error) { - throw new Error('invocation failed', { cause: listResponse.out.error }) - } - - const secondListResponse = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - size, - cursor: listResponse.out.ok.after, - }, - }) - .execute(connection) - if (secondListResponse.out.error) { - throw new Error('invocation failed', { - cause: secondListResponse.out.error, - }) - } - - const prevListResponse = await StoreCapabilities.list - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - size, - cursor: secondListResponse.out.ok.before, - pre: true, - }, - }) - .execute(connection) - if (prevListResponse.out.error) { - throw new Error('invocation failed', { - cause: prevListResponse.out.error, - }) - } - - assert.equal(listResponse.out.ok.results.length, 3) - // listResponse is the first page. we used its after to get the second page, and then used the before of the second - // page with the `pre` caveat to list the first page again. the results and cursors should remain the same. - assert.deepEqual( - prevListResponse.out.ok.results[0], - listResponse.out.ok.results[0] - ) - assert.deepEqual( - prevListResponse.out.ok.results[1], - listResponse.out.ok.results[1] - ) - assert.deepEqual( - prevListResponse.out.ok.results[2], - listResponse.out.ok.results[2] - ) - assert.deepEqual(prevListResponse.out.ok.before, listResponse.out.ok.before) - assert.deepEqual(prevListResponse.out.ok.after, listResponse.out.ok.after) - }, - - 'store/get returns shard info': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const data = [ - new Uint8Array([11, 22, 34, 44, 55]), - new Uint8Array([22, 34, 44, 55, 66]), - ] - const links = [] - for (const datum of data) { - const storeAdd = await StoreCapabilities.add - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - nb: { link: await CAR.codec.link(datum), size: datum.byteLength }, - proofs: [proof], - }) - .execute(connection) - - if (storeAdd.out.error) { - throw new Error('invocation failed', { cause: storeAdd }) - } - - assert.equal(storeAdd.out.ok.status, 'upload') - links.push(storeAdd.out.ok.link) - } - - const storeGet = await StoreCapabilities.get - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - link: links[0], - }, - }) - .execute(connection) - - if (storeGet.out.error) { - throw new Error('invocation failed', { cause: storeGet }) - } - - assert.deepEqual(storeGet.out.ok.link, links[0]) - assert.equal(storeGet.out.ok.size, data[0].byteLength) - assert.ok(storeGet.out.ok.insertedAt) - }, - - 'store/get returns StoreItemNotFound Failure': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - const link = await CAR.codec.link(new Uint8Array([11, 22, 34, 44, 55])) - - const storeGet = await StoreCapabilities.get - .invoke({ - issuer: alice, - audience: connection.id, - with: spaceDid, - proofs: [proof], - nb: { - link, - }, - }) - .execute(connection) - - assert.ok(storeGet.out.error) - assert.equal(storeGet.out.error?.name, 'StoreItemNotFound') - }, -} diff --git a/packages/upload-api/test/handlers/store.spec.js b/packages/upload-api/test/handlers/store.spec.js deleted file mode 100644 index bbfa9646c..000000000 --- a/packages/upload-api/test/handlers/store.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { test } from '../test.js' -import * as Store from './store.js' - -test({ 'store/*': Store.test }) diff --git a/packages/upload-api/test/handlers/subscription.js b/packages/upload-api/test/handlers/subscription.js index 2e58f60b9..26c375c66 100644 --- a/packages/upload-api/test/handlers/subscription.js +++ b/packages/upload-api/test/handlers/subscription.js @@ -1,4 +1,4 @@ -import { Subscription } from '@web3-storage/capabilities' +import { Subscription } from '@storacha/capabilities' import * as API from '../../src/types.js' import { createServer, connect } from '../../src/lib.js' import { alice, registerSpace } from '../util.js' diff --git a/packages/upload-api/test/handlers/ucan.js b/packages/upload-api/test/handlers/ucan.js index d0e952839..314b18277 100644 --- a/packages/upload-api/test/handlers/ucan.js +++ b/packages/upload-api/test/handlers/ucan.js @@ -1,9 +1,9 @@ import * as API from '../../src/types.js' -import { UCAN, Console } from '@web3-storage/capabilities' +import { UCAN, Console } from '@storacha/capabilities' import { Receipt } from '@ucanto/core' import { ed25519 } from '@ucanto/principal' import { sha256 } from 'multiformats/hashes/sha2' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' import { createServer, connect } from '../../src/lib.js' import { alice, bob, mallory, registerSpace } from '../util.js' @@ -457,7 +457,7 @@ export const test = { const next = parseBlobAddReceiptNext(blobAdd) /** - * @type {import('@web3-storage/capabilities/types').BlobAddress} + * @type {import('@storacha/capabilities/types').BlobAddress} */ // @ts-expect-error receipt out is unknown const address = next.allocate.receipt.out.ok?.address diff --git a/packages/upload-api/test/handlers/upload.js b/packages/upload-api/test/handlers/upload.js index 4f915c0c3..0128233cf 100644 --- a/packages/upload-api/test/handlers/upload.js +++ b/packages/upload-api/test/handlers/upload.js @@ -8,7 +8,7 @@ import { service, } from '../util.js' import { createServer, connect } from '../../src/lib.js' -import { Upload } from '@web3-storage/capabilities' +import { Upload } from '@storacha/capabilities' import * as Result from '../helpers/result.js' // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/classes/batchwriteitemcommand.html diff --git a/packages/upload-api/test/handlers/usage.js b/packages/upload-api/test/handlers/usage.js index 200ab28fc..ed62e06d4 100644 --- a/packages/upload-api/test/handlers/usage.js +++ b/packages/upload-api/test/handlers/usage.js @@ -1,8 +1,9 @@ import * as CAR from '@ucanto/transport/car' -import { Store, Usage } from '@web3-storage/capabilities' +import { Usage } from '@storacha/capabilities' import * as API from '../../src/types.js' import { createServer, connect } from '../../src/lib.js' import { alice, registerSpace } from '../util.js' +import { uploadBlob } from '../helpers/blob.js' /** @type {API.Tests} */ export const test = { @@ -17,17 +18,19 @@ export const test = { const link = await CAR.codec.link(data) const size = data.byteLength - const storeAddRes = await Store.add - .invoke({ + await uploadBlob( + { + connection, issuer: alice, audience: context.id, with: spaceDid, - nb: { link, size }, proofs: [proof], - }) - .execute(connection) - - assert.ok(storeAddRes.out.ok) + }, + { + digest: link.multihash, + bytes: data, + } + ) const usageReportRes = await Usage.report .invoke({ @@ -48,9 +51,5 @@ export const test = { assert.equal(report?.size.final, size) assert.equal(report?.events.length, 1) assert.equal(report?.events[0].delta, size) - assert.equal( - report?.events[0].cause.toString(), - storeAddRes.ran.link().toString() - ) }, } diff --git a/packages/upload-api/test/handlers/web3.storage.js b/packages/upload-api/test/handlers/web3.storage.js deleted file mode 100644 index 092039d91..000000000 --- a/packages/upload-api/test/handlers/web3.storage.js +++ /dev/null @@ -1,750 +0,0 @@ -import * as API from '../../src/types.js' -import { equals } from 'uint8arrays' -import { Absentee } from '@ucanto/principal' -import { sha256 } from 'multiformats/hashes/sha2' -import { Assert } from '@web3-storage/content-claims/capability' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import * as W3sBlobCapabilities from '@web3-storage/capabilities/web3.storage/blob' -import { base64pad } from 'multiformats/bases/base64' - -import { AllocatedMemoryHadNotBeenWrittenToName } from '../../src/blob/lib.js' -import { provisionProvider } from '../helpers/utils.js' -import { createServer, connect } from '../../src/lib.js' -import { alice, bob, createSpace, registerSpace } from '../util.js' -import { parseBlobAddReceiptNext } from '../helpers/blob.js' -import * as Result from '../helpers/result.js' - -/** - * @type {API.Tests} - */ -export const test = { - 'web3.storage/blob/allocate must be invoked on service did': async ( - assert, - context - ) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const serviceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - proofs: [proof], - }) - const blobAllocate = await serviceBlobAllocate.execute(connection) - assert.ok( - String(blobAllocate.out.error?.message).match( - /did:key:.*does not have.*capability provider/ - ) - ) - }, - 'web3.storage/blob/allocate allocates to space and returns presigned url': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const serviceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - }) - const blobAllocate = await serviceBlobAllocate.execute(connection) - if (!blobAllocate.out.ok) { - throw new Error('invocation failed', { cause: blobAllocate }) - } - - // Validate response - assert.equal(blobAllocate.out.ok.size, size) - assert.ok(blobAllocate.out.ok.address) - assert.ok(blobAllocate.out.ok.address?.headers) - assert.ok(blobAllocate.out.ok.address?.url) - assert.ok(blobAllocate.out.ok.address?.expiresAt) - assert.equal( - blobAllocate.out.ok.address?.headers?.['content-length'], - String(size) - ) - assert.deepEqual( - blobAllocate.out.ok.address?.headers?.['x-amz-checksum-sha256'], - base64pad.baseEncode(multihash.digest) - ) - - const url = - blobAllocate.out.ok.address?.url && - new URL(blobAllocate.out.ok.address?.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - const signedHeaders = url.searchParams.get('X-Amz-SignedHeaders') - - assert.equal( - signedHeaders, - 'content-length;host;x-amz-checksum-sha256', - 'content-length and checksum must be part of the signature' - ) - - // Validate allocation state - const spaceAllocations = await context.allocationsStorage.list(spaceDid) - assert.ok(spaceAllocations.ok) - assert.equal(spaceAllocations.ok?.size, 1) - const allocatedEntry = spaceAllocations.ok?.results[0] - if (!allocatedEntry) { - throw new Error('Expected presigned allocatedEntry in response') - } - assert.ok(equals(allocatedEntry.blob.digest, digest)) - assert.equal(allocatedEntry.blob.size, size) - - // Validate presigned url usage - const goodPut = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: blobAllocate.out.ok.address?.headers, - }) - - assert.equal(goodPut.status, 200, await goodPut.text()) - }, - 'web3.storage/blob/allocate does not allocate more space to already allocated content': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const allocation = await W3sBlobCapabilities.allocate - .invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - }) - .execute(connection) - - if (!allocation.out.ok) { - throw new Error('invocation failed', { cause: allocation.out.error }) - } - - // second blob allocate invocation - const reallocation = await W3sBlobCapabilities.allocate - .invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - nonce: 'retry', - }) - .execute(connection) - if (!reallocation.out.ok) { - throw new Error('invocation failed', { cause: reallocation.out.error }) - } - - // Validate response - assert.equal(reallocation.out.ok.size, 0) - assert.ok(!!reallocation.out.ok.address) - }, - 'web3.storage/blob/allocate can allocate to different space after write to one space': - async (assert, context) => { - const { proof: aliceProof, spaceDid: aliceSpaceDid } = - await registerSpace(alice, context) - const { proof: bobProof, spaceDid: bobSpaceDid } = await registerSpace( - bob, - context, - 'bob' - ) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocations - const aliceBlobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: aliceSpaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [aliceProof], - }) - const bobBlobAddInvocation = BlobCapabilities.add.invoke({ - issuer: bob, - audience: context.id, - with: bobSpaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [bobProof], - }) - - // invoke `web3.storage/blob/allocate` capabilities on alice space - const aliceServiceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await aliceBlobAddInvocation.delegate()).cid, - space: aliceSpaceDid, - }, - }) - const aliceBlobAllocate = await aliceServiceBlobAllocate.execute( - connection - ) - if (!aliceBlobAllocate.out.ok) { - throw new Error('invocation failed', { cause: aliceBlobAllocate }) - } - // there is address to write - assert.ok(aliceBlobAllocate.out.ok.address) - assert.equal(aliceBlobAllocate.out.ok.size, size) - - // write to presigned url - const url = - aliceBlobAllocate.out.ok.address?.url && - new URL(aliceBlobAllocate.out.ok.address?.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - const goodPut = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: aliceBlobAllocate.out.ok.address?.headers, - }) - - assert.equal(goodPut.status, 200, await goodPut.text()) - - // invoke `web3.storage/blob/allocate` capabilities on bob space - const bobServiceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await bobBlobAddInvocation.delegate()).cid, - space: bobSpaceDid, - }, - }) - const bobBlobAllocate = await bobServiceBlobAllocate.execute(connection) - if (!bobBlobAllocate.out.ok) { - throw new Error('invocation failed', { cause: bobBlobAllocate }) - } - // there is no address to write - assert.ok(!bobBlobAllocate.out.ok.address) - assert.equal(bobBlobAllocate.out.ok.size, size) - - // Validate allocation state - const aliceSpaceAllocations = await context.allocationsStorage.list( - aliceSpaceDid - ) - assert.ok(aliceSpaceAllocations.ok) - assert.equal(aliceSpaceAllocations.ok?.size, 1) - - const bobSpaceAllocations = await context.allocationsStorage.list( - bobSpaceDid - ) - assert.ok(bobSpaceAllocations.ok) - assert.equal(bobSpaceAllocations.ok?.size, 1) - }, - 'web3.storage/blob/allocate creates presigned url that can only PUT a payload with right length': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const longer = new Uint8Array([11, 22, 34, 44, 55, 66]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const serviceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - }) - const blobAllocate = await serviceBlobAllocate.execute(connection) - if (!blobAllocate.out.ok) { - throw new Error('invocation failed', { cause: blobAllocate }) - } - // there is address to write - assert.ok(blobAllocate.out.ok.address) - assert.equal(blobAllocate.out.ok.size, size) - - // write to presigned url - const url = - blobAllocate.out.ok.address?.url && - new URL(blobAllocate.out.ok.address?.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - const contentLengthFailSignature = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: longer, - headers: { - ...blobAllocate.out.ok.address?.headers, - 'content-length': longer.byteLength.toString(10), - }, - }) - - assert.equal( - contentLengthFailSignature.status >= 400, - true, - 'should fail to upload as content-length differs from that used to sign the url' - ) - }, - 'web3.storage/blob/allocate creates presigned url that can PUT a payload with exact bytes': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const other = new Uint8Array([10, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const serviceBlobAllocate = W3sBlobCapabilities.allocate.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - }) - const blobAllocate = await serviceBlobAllocate.execute(connection) - if (!blobAllocate.out.ok) { - throw new Error('invocation failed', { cause: blobAllocate }) - } - // there is address to write - assert.ok(blobAllocate.out.ok.address) - assert.equal(blobAllocate.out.ok.size, size) - - // write to presigned url - const url = - blobAllocate.out.ok.address?.url && - new URL(blobAllocate.out.ok.address?.url) - if (!url) { - throw new Error('Expected presigned url in response') - } - const failChecksum = await fetch(url, { - method: 'PUT', - mode: 'cors', - body: other, - headers: blobAllocate.out.ok.address?.headers, - }) - - assert.equal( - failChecksum.status, - 400, - 'should fail to upload any other data.' - ) - }, - 'web3.storage/blob/allocate disallowed if invocation fails access verification': - async (assert, context) => { - const { proof, space, spaceDid } = await createSpace(alice) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - - // invoke `web3.storage/blob/allocate` - const task = { - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - cause: (await blobAddInvocation.delegate()).cid, - space: spaceDid, - }, - } - const blobAllocate = await W3sBlobCapabilities.allocate - .invoke(task) - .execute(connection) - - assert.ok(blobAllocate.out.error) - assert.equal(blobAllocate.out.error?.message.includes('no storage'), true) - - // Register space and retry - const account = Absentee.from({ - id: 'did:mailto:test.web3.storage:alice', - }) - const providerAdd = await provisionProvider({ - service: /** @type {API.Signer>} */ (context.signer), - agent: alice, - space, - account, - connection, - }) - assert.ok(providerAdd.out.ok) - - const retryBlobAllocate = await W3sBlobCapabilities.allocate - .invoke({ - ...task, - nonce: 'retry', - }) - .execute(connection) - assert.equal(retryBlobAllocate.out.error, undefined) - }, - 'web3.storage/blob/accept returns site delegation': async ( - assert, - context - ) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const blobAdd = await blobAddInvocation.execute(connection) - if (!blobAdd.out.ok) { - throw new Error('invocation failed', { cause: blobAdd }) - } - - // parse receipt next - const next = parseBlobAddReceiptNext(blobAdd) - - /** @type {import('@web3-storage/capabilities/types').BlobAddress} */ - // @ts-expect-error receipt type is unknown - const address = next.allocate.receipt.out.ok.address - - // Store the blob to the address - const goodPut = await fetch(address.url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: address.headers, - }) - assert.equal(goodPut.status, 200, await goodPut.text()) - - // invoke `web3.storage/blob/accept` - const serviceBlobAccept = W3sBlobCapabilities.accept.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - space: spaceDid, - _put: { 'ucan/await': ['.out.ok', next.put.task.link()] }, - }, - }) - const blobAccept = await serviceBlobAccept.execute(connection) - if (!blobAccept.out.ok) { - throw new Error('invocation failed', { cause: blobAccept }) - } - // Validate out - assert.ok(blobAccept.out.ok) - assert.ok(blobAccept.out.ok.site) - - // Validate effect - assert.equal(blobAccept.fx.fork.length, 1) - /** @type {import('@ucanto/interface').Delegation} */ - // @ts-expect-error delegation not assignable to Effect per TS understanding - const delegation = blobAccept.fx.fork[0] - assert.equal(delegation.capabilities.length, 1) - assert.ok(delegation.capabilities[0].can, Assert.location.can) - assert.ok( - equals( - // @ts-expect-error nb unknown - delegation.capabilities[0].nb.content.digest, - digest - ) - ) - // @ts-expect-error nb unknown - const locations = delegation.capabilities[0].nb.location - assert.equal(locations.length, 1) - - const loc = Result.unwrap( - await context.blobsStorage.createDownloadUrl(multihash) - ) - assert.ok(locations.includes(loc)) - }, - 'web3.storage/blob/accept fails to provide site delegation when blob was not stored': - async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - - // prepare data - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // create service connection - const connection = connect({ - id: context.id, - channel: createServer(context), - }) - - // create `blob/add` invocation - const blobAddInvocation = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const blobAdd = await blobAddInvocation.execute(connection) - if (!blobAdd.out.ok) { - throw new Error('invocation failed', { cause: blobAdd }) - } - - // parse receipt next - const next = parseBlobAddReceiptNext(blobAdd) - - // invoke `web3.storage/blob/accept` - const serviceBlobAccept = W3sBlobCapabilities.accept.invoke({ - issuer: context.id, - audience: context.id, - with: context.id.did(), - nb: { - blob: { - digest, - size, - }, - space: spaceDid, - _put: { 'ucan/await': ['.out.ok', next.put.task.link()] }, - }, - proofs: [proof], - }) - const blobAccept = await serviceBlobAccept.execute(connection) - // Validate out error - assert.ok(blobAccept.out.error) - assert.equal( - blobAccept.out.error?.name, - AllocatedMemoryHadNotBeenWrittenToName - ) - }, -} diff --git a/packages/upload-api/test/handlers/web3.storage.spec.js b/packages/upload-api/test/handlers/web3.storage.spec.js deleted file mode 100644 index b68050534..000000000 --- a/packages/upload-api/test/handlers/web3.storage.spec.js +++ /dev/null @@ -1,4 +0,0 @@ -import { test } from '../test.js' -import * as W3s from './web3.storage.js' - -test({ 'web3.storage/*': W3s.test }) diff --git a/packages/upload-api/test/helpers/blob.js b/packages/upload-api/test/helpers/blob.js index acf24780c..0960394df 100644 --- a/packages/upload-api/test/helpers/blob.js +++ b/packages/upload-api/test/helpers/blob.js @@ -1,10 +1,10 @@ import * as API from '../../src/types.js' import { ed25519 } from '@ucanto/principal' import { Delegation, Receipt } from '@ucanto/core' -import * as W3sBlobCapabilities from '@web3-storage/capabilities/web3.storage/blob' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import * as HTTPCapabilities from '@web3-storage/capabilities/http' -import * as UCAN from '@web3-storage/capabilities/ucan' +import * as BlobCapabilities from '@storacha/capabilities/blob' +import * as SpaceBlobCapabilities from '@storacha/capabilities/space/blob' +import * as HTTPCapabilities from '@storacha/capabilities/http' +import * as UCAN from '@storacha/capabilities/ucan' import { createConcludeInvocation, getConcludeReceipt, @@ -22,7 +22,7 @@ export function parseBlobAddReceiptNext(receipt) { // @ts-expect-error read only effect const forkInvocations = receipt.fx.fork const allocateTask = forkInvocations.find( - (fork) => fork.capabilities[0].can === W3sBlobCapabilities.allocate.can + (fork) => fork.capabilities[0].can === BlobCapabilities.allocate.can ) const concludefxs = forkInvocations.filter( (fork) => fork.capabilities[0].can === UCAN.conclude.can @@ -31,7 +31,7 @@ export function parseBlobAddReceiptNext(receipt) { (fork) => fork.capabilities[0].can === HTTPCapabilities.put.can ) const acceptTask = forkInvocations.find( - (fork) => fork.capabilities[0].can === W3sBlobCapabilities.accept.can + (fork) => fork.capabilities[0].can === BlobCapabilities.accept.can ) if (!allocateTask || !concludefxs.length || !putTask || !acceptTask) { @@ -90,27 +90,25 @@ export function parseBlobAddReceiptNext(receipt) { } /** - * @param {API.UcantoServerTestContext} context * @param {object} config * @param {API.ConnectionView} config.connection * @param {API.Signer} config.issuer * @param {API.Verifier} config.audience * @param {API.SpaceDID} config.with * @param {API.Delegation[]} config.proofs - * @param {{ cid: API.UnknownLink, bytes: Uint8Array }} content + * @param {{ digest: API.MultihashDigest, bytes: Uint8Array }} content */ export const uploadBlob = async ( - context, { connection, issuer, audience, with: resource, proofs }, content ) => { - const blobAdd = BlobCapabilities.add.invoke({ + const blobAdd = SpaceBlobCapabilities.add.invoke({ issuer, audience, with: resource, nb: { blob: { - digest: content.cid.multihash.bytes, + digest: content.digest.bytes, size: content.bytes.length, }, }, @@ -146,7 +144,7 @@ export const uploadBlob = async ( with: derivedSigner.toDIDKey(), nb: { body: { - digest: content.cid.multihash.bytes, + digest: content.digest.bytes, size: content.bytes.length, }, url: { diff --git a/packages/upload-api/test/helpers/context.js b/packages/upload-api/test/helpers/context.js index a6f58a3ac..16a090ef7 100644 --- a/packages/upload-api/test/helpers/context.js +++ b/packages/upload-api/test/helpers/context.js @@ -4,7 +4,7 @@ import { getMockService, getStoreImplementations as getFilecoinStoreImplementations, getQueueImplementations as getFilecoinQueueImplementations, -} from '@web3-storage/filecoin-api/test/context/service' +} from '@storacha/filecoin-api/test/context/service' import * as Email from '../../src/utils/email.js' import { create as createRevocationChecker } from '../../src/utils/revocation.js' import { createServer, connect } from '../../src/lib.js' @@ -29,7 +29,7 @@ export const createContext = async ( const signer = await Signer.generate() const aggregatorSigner = await Signer.generate() const dealTrackerSigner = await Signer.generate() - const id = signer.withDID('did:web:test.web3.storage') + const id = signer.withDID('did:web:test.upload.storacha.network') const service = getMockService() const dealTrackerConnection = getConnection( @@ -49,7 +49,10 @@ export const createContext = async ( } = getFilecoinStoreImplementations() const email = Email.debug() - const externalServices = await getExternalServiceImplementations(options) + const externalServices = await getExternalServiceImplementations({ + ...options, + serviceID: id, + }) /** @type { import('../../src/types.js').UcantoServerContext } */ const serviceContext = { @@ -61,7 +64,6 @@ export const createContext = async ( url: new URL('http://localhost:8787'), ...serviceStores, ...externalServices, - getServiceConnection: () => connection, ...createRevocationChecker({ revocationsStorage: serviceStores.revocationsStorage, }), @@ -75,7 +77,6 @@ export const createContext = async ( }, }, // Filecoin - maxUploadSize: 5_000_000_000, filecoinSubmitQueue, pieceOfferQueue, pieceStore, @@ -89,6 +90,14 @@ export const createContext = async ( audience: dealTrackerSigner, }, }, + // Legacy dependencies. + // The following dependencies are legacy and will eventually be removed. + // @ts-expect-error legacy dependency not used or tested here + maxUploadSize: null, + // @ts-expect-error legacy dependency not used or tested here + storeTable: {}, + // @ts-expect-error legacy dependency not used or tested here + carStoreBucket: {}, } const connection = connect({ @@ -114,7 +123,6 @@ export const createContext = async ( */ export const cleanupContext = (context) => Promise.all([ - context.carStoreBucket.deactivate(), - context.blobsStorage.deactivate(), context.claimsService.deactivate(), + ...context.storageProviders.map((p) => p.deactivate()), ]) diff --git a/packages/upload-api/test/helpers/utils.js b/packages/upload-api/test/helpers/utils.js index ee7a67175..37835f1e5 100644 --- a/packages/upload-api/test/helpers/utils.js +++ b/packages/upload-api/test/helpers/utils.js @@ -5,10 +5,10 @@ import * as Server from '@ucanto/server' import * as Client from '@ucanto/client' import * as CAR from '@ucanto/transport/car' import * as Context from './context.js' -import { Provider, UCAN, Space } from '@web3-storage/capabilities' -import * as DidMailto from '@web3-storage/did-mailto' +import { Provider, UCAN, Space } from '@storacha/capabilities' +import * as DidMailto from '@storacha/did-mailto' import * as API from '../types.js' -import { stringToDelegation } from '@web3-storage/access/encoding' +import { stringToDelegation } from '@storacha/access/encoding' export { Context } @@ -37,11 +37,17 @@ export const mallory = ed25519.parse( 'MgCYtH0AvYxiQwBG6+ZXcwlXywq9tI50G2mCAUJbwrrahkO0B0elFYkl3Ulf3Q3A/EvcVY0utb4etiSE8e6pi4H0FEmU=' ) -export const w3 = ed25519 - .parse( - 'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8=' - ) - .withDID('did:web:test.web3.storage') +/** did:key:z6MkrZ1r5XBFZjBU34qyD8fueMbMRkKw17BZaq2ivKFjnz2z */ +export const w3Signer = ed25519.parse( + 'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8=' +) +export const w3 = w3Signer.withDID('did:web:test.web3.storage') + +/** did:key:z6MkuKJgV8DKxiAF5oaUcT8ckg8kZUoBe6yavSLnHn5ZgyAP */ +export const gatewaySigner = ed25519.parse( + 'MgCaNpGXCEX0+BxxE4SjSStrxU9Ru/Im+HGNQ/JJx3lDoI+0B3NWjWW3G8OzjbazZjanjM3kgfcZbvpyxv20jHtmcTtg=' +) +export const gateway = gatewaySigner.withDID('did:web:w3s.link') /** * Creates a server for the given service. @@ -202,7 +208,7 @@ export const queue = (buffer = []) => { /** * @param {Types.Signer} issuer * @param {Types.Signer} service - * @param {Types.ConnectionView} conn + * @param {Types.ConnectionView} conn * @param {`${string}@${string}`} email */ export async function createSpace(issuer, service, conn, email) { @@ -254,7 +260,7 @@ export async function extractConfirmInvocation(confirmationUrl) { } /** - * @param {API.ConnectionView} connection + * @param {API.ConnectionView} connection * @param {{ url: string|URL }} confirmation */ export async function confirmConfirmationUrl(connection, confirmation) { diff --git a/packages/upload-api/test/lib.js b/packages/upload-api/test/lib.js index d1c932843..046956264 100644 --- a/packages/upload-api/test/lib.js +++ b/packages/upload-api/test/lib.js @@ -1,22 +1,18 @@ import * as AccessAuthorize from './handlers/access/authorize.js' import * as AccessClaim from './handlers/access/claim.js' import * as AccessDelegate from './handlers/access/delegate.js' -import * as AdminStoreInspect from './handlers/admin/store/inspect.js' import * as AdminUploadInspect from './handlers/admin/upload/inspect.js' import * as RateLimitAdd from './handlers/rate-limit/add.js' import * as RateLimitList from './handlers/rate-limit/list.js' import * as RateLimitRemove from './handlers/rate-limit/remove.js' -import * as Store from './handlers/store.js' import * as Blob from './handlers/blob.js' -import * as Web3Storage from './handlers/web3.storage.js' import * as Ucan from './handlers/ucan.js' import * as Subscription from './handlers/subscription.js' import * as Upload from './handlers/upload.js' import * as Plan from './handlers/plan.js' import * as Usage from './handlers/usage.js' import * as Index from './handlers/index.js' -import { test as allocationsStorageTests } from './storage/allocations-storage-tests.js' -import { test as blobsStorageTests } from './storage/blobs-storage-tests.js' +import { test as blobRegistryTests } from './storage/blob-registry-tests.js' import { test as agentStoreTests } from './storage/agent-store-tests.js' import { test as delegationsStorageTests } from './storage/delegations-storage-tests.js' import { test as provisionsStorageTests } from './storage/provisions-storage-tests.js' @@ -29,11 +25,9 @@ export * as Context from './helpers/context.js' export * from './util.js' export const test = { - ...Store.test, ...Blob.test, ...Index.test, ...Upload.test, - ...Web3Storage.test, ...Ucan.test, } @@ -43,8 +37,7 @@ export const storageTests = { ...rateLimitsStorageTests, ...revocationsStorageTests, ...plansStorageTests, - ...allocationsStorageTests, - ...blobsStorageTests, + ...blobRegistryTests, ...agentStoreTests, } @@ -52,15 +45,12 @@ export const handlerTests = { ...AccessAuthorize, ...AccessClaim, ...AccessDelegate, - ...AdminStoreInspect, ...AdminUploadInspect, ...RateLimitAdd, ...RateLimitList, ...RateLimitRemove, - ...Store.test, ...Blob.test, ...Index.test, - ...Web3Storage.test, ...Ucan.test, ...Subscription.test, ...Upload.test, @@ -69,19 +59,16 @@ export const handlerTests = { } export { - Store, Upload, Blob, Index, - Web3Storage, Ucan, delegationsStorageTests, provisionsStorageTests, rateLimitsStorageTests, revocationsStorageTests, plansStorageTests, - allocationsStorageTests, - blobsStorageTests, + blobRegistryTests, agentStoreTests, DebugEmail, } diff --git a/packages/upload-api/test/service.js b/packages/upload-api/test/service.js index 983d4abd1..3752fcf62 100644 --- a/packages/upload-api/test/service.js +++ b/packages/upload-api/test/service.js @@ -1,6 +1,6 @@ import * as API from './types.js' import { alice } from './helpers/utils.js' -import { Space } from '@web3-storage/capabilities' +import { Space } from '@storacha/capabilities' import { parseLink } from '@ucanto/core' /** diff --git a/packages/upload-api/test/storage/agent-store-tests.js b/packages/upload-api/test/storage/agent-store-tests.js index 0dda643e9..1b304d9b0 100644 --- a/packages/upload-api/test/storage/agent-store-tests.js +++ b/packages/upload-api/test/storage/agent-store-tests.js @@ -1,8 +1,8 @@ import * as API from '../../src/types.js' import { sha256 } from 'multiformats/hashes/sha2' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import { Console } from '@web3-storage/capabilities' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' +import { Console } from '@storacha/capabilities' import { alice, registerSpace } from '../util.js' import { Message, Receipt } from '@ucanto/core' diff --git a/packages/upload-api/test/storage/agent-store.js b/packages/upload-api/test/storage/agent-store.js index 42ed60137..c263d28fd 100644 --- a/packages/upload-api/test/storage/agent-store.js +++ b/packages/upload-api/test/storage/agent-store.js @@ -2,6 +2,7 @@ import * as API from '../../src/types.js' import { CAR, Invocation, Receipt } from '@ucanto/core' import { RecordNotFound } from '../../src/errors.js' +/** @returns {API.AgentStore} */ export const memory = () => new AgentStore() /** diff --git a/packages/upload-api/test/storage/allocations-storage-tests.js b/packages/upload-api/test/storage/allocations-storage-tests.js deleted file mode 100644 index 910093c6b..000000000 --- a/packages/upload-api/test/storage/allocations-storage-tests.js +++ /dev/null @@ -1,367 +0,0 @@ -import * as API from '../../src/types.js' - -import { sha256 } from 'multiformats/hashes/sha2' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import { equals } from 'uint8arrays' - -import { - RecordKeyConflictName, - RecordNotFoundErrorName, -} from '../../src/errors.js' -import { alice, bob, registerSpace } from '../util.js' - -/** - * @type {API.Tests} - */ -export const test = { - 'should store allocations': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // invoke `blob/add` - const blobAdd = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const cause = (await blobAdd.delegate()).link() - const allocationInsert = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - - assert.ok(allocationInsert.ok) - assert.ok(allocationInsert.ok?.blob) - }, - 'should store same allocation once': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // invoke `blob/add` - const blobAdd = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const cause = (await blobAdd.delegate()).link() - const allocationInsert0 = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - assert.ok(allocationInsert0.ok) - - const allocationInsert1 = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - assert.ok(allocationInsert1.error) - assert.equal(allocationInsert1.error?.name, RecordKeyConflictName) - }, - 'should get allocations only when available': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - const allocationGet0 = await allocationsStorage.get(spaceDid, multihash) - assert.ok(allocationGet0.error) - assert.equal(allocationGet0.error?.name, RecordNotFoundErrorName) - - // invoke `blob/add` - const blobAdd = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const cause = (await blobAdd.delegate()).link() - const allocationInsert = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - - assert.ok(allocationInsert.ok) - assert.ok(allocationInsert.ok?.blob) - - const allocationGet1 = await allocationsStorage.get(spaceDid, multihash) - assert.ok(allocationGet1.ok) - assert.ok(allocationGet1.ok?.blob) - assert.equal(allocationGet1.ok?.blob.size, size) - assert.ok( - equals(digest, allocationGet1.ok?.blob.digest || new Uint8Array()) - ) - assert.ok(allocationGet1.ok?.cause) - }, - 'should verify allocations exist': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - const allocationExist0 = await allocationsStorage.exists( - spaceDid, - multihash - ) - assert.ok(!allocationExist0.error) - assert.ok(!allocationExist0.ok) - - // invoke `blob/add` - const blobAdd = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const cause = (await blobAdd.delegate()).link() - const allocationInsert = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - - assert.ok(allocationInsert.ok) - assert.ok(allocationInsert.ok?.blob) - - const allocationExist1 = await allocationsStorage.exists( - spaceDid, - multihash - ) - assert.ok(allocationExist1.ok) - assert.ok(!allocationExist1.error) - }, - 'should list all allocations in a space': async (assert, context) => { - const { proof: aliceProof, spaceDid: aliceSpaceDid } = await registerSpace( - alice, - context - ) - const { proof: bobProof, spaceDid: bobSpaceDid } = await registerSpace( - bob, - context - ) - const allocationsStorage = context.allocationsStorage - - // Data for alice - const data0 = new Uint8Array([11, 22, 34, 44, 55]) - const multihash0 = await sha256.digest(data0) - const digest0 = multihash0.bytes - const size0 = data0.byteLength - const blob0 = { - digest: digest0, - size: size0, - } - // Data for bob - const data1 = new Uint8Array([66, 77, 88, 99, 0]) - const multihash1 = await sha256.digest(data1) - const digest1 = multihash1.bytes - const size1 = data1.byteLength - const blob1 = { - digest: digest1, - size: size1, - } - - // Get alice empty allocations - const allocationsAllice0 = await allocationsStorage.list(aliceSpaceDid) - assert.ok(allocationsAllice0.ok) - assert.deepEqual(allocationsAllice0.ok?.results, []) - assert.equal(allocationsAllice0.ok?.size, 0) - - // invoke `blob/add` with alice - const aliceBlobAdd0 = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: aliceSpaceDid, - nb: { - blob: blob0, - }, - proofs: [aliceProof], - }) - const aliceInvocation = (await aliceBlobAdd0.delegate()).link() - - // Add alice allocations - const aliceAllocationInsert0 = await allocationsStorage.insert({ - space: aliceSpaceDid, - blob: blob0, - cause: aliceInvocation, - }) - assert.ok(aliceAllocationInsert0.ok) - - // invoke `blob/add` with bob - const bobBlobAdd = BlobCapabilities.add.invoke({ - issuer: bob, - audience: context.id, - with: bobSpaceDid, - nb: { - blob: blob1, - }, - proofs: [bobProof], - }) - const cause = (await bobBlobAdd.delegate()).link() - - // Add bob allocations - const bobAllocationInsert = await allocationsStorage.insert({ - space: bobSpaceDid, - blob: blob1, - cause, - }) - assert.ok(bobAllocationInsert.ok) - - const allocationsAllice1 = await allocationsStorage.list(aliceSpaceDid) - assert.ok(allocationsAllice1.ok) - assert.equal(allocationsAllice1.ok?.size, 1) - assert.equal(allocationsAllice1.ok?.results.length, 1) - assert.ok( - equals( - blob0.digest, - allocationsAllice1.ok?.results[0].blob.digest || new Uint8Array() - ) - ) - - // Add bob's data on alice alloctions - const aliceBlobAdd01 = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: aliceSpaceDid, - nb: { - blob: blob1, - }, - proofs: [aliceProof], - }) - const aliceInvocation1 = (await aliceBlobAdd01.delegate()).link() - - // Add alice allocations - const aliceAllocationInsert1 = await allocationsStorage.insert({ - space: aliceSpaceDid, - blob: blob1, - cause: aliceInvocation1, - }) - assert.ok(aliceAllocationInsert1.ok) - - const allocationsAllice2 = await allocationsStorage.list(aliceSpaceDid) - assert.ok(allocationsAllice2.ok) - assert.equal(allocationsAllice2.ok?.size, 2) - assert.equal(allocationsAllice2.ok?.results.length, 2) - assert.ok( - allocationsAllice2.ok?.results.find((res) => - equals(res.blob.digest, blob0.digest) - ) - ) - assert.ok( - allocationsAllice2.ok?.results.find((res) => - equals(res.blob.digest, blob1.digest) - ) - ) - }, - 'should fail to remove non existent allocations on a space': async ( - assert, - context - ) => { - const { spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - - const removeResult = await allocationsStorage.remove(spaceDid, multihash) - - assert.ok(removeResult.error) - assert.equal(removeResult.error?.name, RecordNotFoundErrorName) - }, - 'should remove existent allocations on a space': async (assert, context) => { - const { proof, spaceDid } = await registerSpace(alice, context) - const allocationsStorage = context.allocationsStorage - - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash = await sha256.digest(data) - const digest = multihash.bytes - const size = data.byteLength - - // invoke `blob/add` - const blobAdd = BlobCapabilities.add.invoke({ - issuer: alice, - audience: context.id, - with: spaceDid, - nb: { - blob: { - digest, - size, - }, - }, - proofs: [proof], - }) - const cause = (await blobAdd.delegate()).link() - const allocationInsert0 = await allocationsStorage.insert({ - space: spaceDid, - blob: { - digest, - size, - }, - cause, - }) - assert.ok(allocationInsert0.ok) - - const removeResult = await allocationsStorage.remove(spaceDid, multihash) - assert.ok(removeResult.ok) - assert.equal(removeResult.ok?.size, size) - }, -} diff --git a/packages/upload-api/test/storage/allocations-storage.js b/packages/upload-api/test/storage/allocations-storage.js deleted file mode 100644 index 27634c118..000000000 --- a/packages/upload-api/test/storage/allocations-storage.js +++ /dev/null @@ -1,125 +0,0 @@ -import * as Types from '../../src/types.js' -import { equals } from 'uint8arrays/equals' -import { RecordKeyConflict, RecordNotFound } from '../../src/errors.js' - -/** - * @implements {Types.AllocationsStorage} - */ -export class AllocationsStorage { - constructor() { - /** @type {(Types.BlobAddInput & Types.BlobListItem)[]} */ - this.items = [] - } - - /** - * @param {Types.BlobAddInput} input - * @returns {ReturnType} - */ - async insert({ space, cause, ...output }) { - if ( - this.items.some( - (i) => i.space === space && equals(i.blob.digest, output.blob.digest) - ) - ) { - return { - error: new RecordKeyConflict(), - } - } - this.items.unshift({ - space, - cause, - ...output, - insertedAt: new Date().toISOString(), - }) - return { ok: output } - } - - /** - * @param {Types.DID} space - * @param {Types.MultihashDigest} digest - * @returns {ReturnType} - */ - async get(space, digest) { - const item = this.items.find( - (i) => i.space === space && equals(i.blob.digest, digest.bytes) - ) - if (!item) { - return { error: new RecordNotFound() } - } - return { ok: item } - } - - /** - * @param {Types.DID} space - * @param {Types.MultihashDigest} digest - * @returns {ReturnType} - */ - async exists(space, digest) { - const item = this.items.find( - (i) => i.space === space && equals(i.blob.digest, digest.bytes) - ) - return { ok: !!item } - } - - /** - * @param {Types.DID} space - * @param {Types.MultihashDigest} digest - * @returns {ReturnType} - */ - async remove(space, digest) { - const item = this.items.find( - (i) => i.space === space && equals(i.blob.digest, digest.bytes) - ) - if (!item) { - return { error: new RecordNotFound() } - } - this.items = this.items.filter((i) => i !== item) - return { - ok: { - size: item.blob.size, - }, - } - } - - /** - * @param {Types.DID} space - * @param {Types.ListOptions} options - * @returns {ReturnType} - */ - async list( - space, - { cursor = '0', pre = false, size = this.items.length } = {} - ) { - const offset = parseInt(cursor, 10) - const items = pre ? this.items.slice(0, offset) : this.items.slice(offset) - - const matches = [...items.entries()] - .filter(([n, item]) => item.space === space) - .slice(0, size) - - if (matches.length === 0) { - return { ok: { size: 0, results: [] } } - } - - const first = matches[0] - const last = matches[matches.length - 1] - - const start = first[0] || 0 - const end = last[0] || 0 - const values = matches.map(([_, item]) => item) - - const [before, after, results] = pre - ? [`${start}`, `${end + 1}`, values] - : [`${start + offset}`, `${end + 1 + offset}`, values] - - return { - ok: { - size: values.length, - before, - after, - cursor: after, - results, - }, - } - } -} diff --git a/packages/upload-api/test/storage/allocations-storage.spec.js b/packages/upload-api/test/storage/allocations-storage.spec.js deleted file mode 100644 index 817c610f1..000000000 --- a/packages/upload-api/test/storage/allocations-storage.spec.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as AllocationsStorage from './allocations-storage-tests.js' -import { test } from '../test.js' -test({ 'in memory allocations storage': AllocationsStorage.test }) diff --git a/packages/upload-api/test/storage/blob-registry-tests.js b/packages/upload-api/test/storage/blob-registry-tests.js new file mode 100644 index 000000000..3e532855f --- /dev/null +++ b/packages/upload-api/test/storage/blob-registry-tests.js @@ -0,0 +1,167 @@ +import * as API from '../../src/types.js' +import { sha256 } from 'multiformats/hashes/sha2' +import { equals } from 'multiformats/bytes' +import { alice, bob, randomCID, registerSpace } from '../util.js' +import { EntryExists, EntryNotFound } from '../../src/blob.js' + +/** + * @type {API.Tests} + */ +export const test = { + 'should register a blob': async (assert, context) => { + const { spaceDid: space } = await registerSpace(alice, context) + const { registry } = context + const data = new Uint8Array([11, 22, 34, 44, 55]) + const digest = await sha256.digest(data) + const blob = { digest: digest, size: data.length } + const cause = await randomCID() + const registration = await registry.register({ space, blob, cause }) + assert.ok(registration.ok) + }, + 'should register same blob in the same space once': async ( + assert, + context + ) => { + const { spaceDid: space } = await registerSpace(alice, context) + const { registry } = context + const data = new Uint8Array([11, 22, 34, 44, 55]) + const digest = await sha256.digest(data) + const blob = { digest: digest, size: data.length } + const cause = await randomCID() + const registration0 = await registry.register({ space, blob, cause }) + assert.ok(registration0.ok) + const registration1 = await registry.register({ space, blob, cause }) + assert.ok(registration1.error) + assert.equal(registration1.error?.name, EntryExists.name) + }, + 'should get entry only when available': async (assert, context) => { + const { spaceDid: space } = await registerSpace(alice, context) + const { registry } = context + + const data = new Uint8Array([11, 22, 34, 44, 55]) + const digest = await sha256.digest(data) + + const find0 = await registry.find(space, digest) + assert.ok(find0.error) + assert.equal(find0.error?.name, EntryNotFound.name) + + const blob = { digest: digest, size: data.length } + const cause = await randomCID() + const registration = await registry.register({ space, blob, cause }) + assert.ok(registration.ok) + + const find1 = await registry.find(space, digest) + assert.ok(find1.ok) + assert.ok(find1.ok?.blob) + assert.equal(find1.ok?.blob.size, data.length) + assert.ok( + equals(digest.bytes, find1.ok?.blob.digest.bytes || new Uint8Array()) + ) + assert.equal(find1.ok?.cause.toString(), cause.toString()) + }, + 'should list all blobs in a space': async (assert, context) => { + const { spaceDid: aliceSpace } = await registerSpace(alice, context) + const { spaceDid: bobSpace } = await registerSpace(bob, context) + const { registry } = context + + // Data for alice + const data0 = new Uint8Array([11, 22, 34, 44, 55]) + const digest0 = await sha256.digest(data0) + const blob0 = { digest: digest0, size: data0.length } + const cause0 = await randomCID() + // Data for bob + const data1 = new Uint8Array([66, 77, 88, 99, 0]) + const digest1 = await sha256.digest(data1) + const blob1 = { digest: digest1, size: data1.length } + const cause1 = await randomCID() + + // Get alice empty entries + const entriesAlice0 = await registry.entries(aliceSpace) + assert.ok(entriesAlice0.ok) + assert.deepEqual(entriesAlice0.ok?.results, []) + assert.equal(entriesAlice0.ok?.size, 0) + + // Add alice entries + const aliceReg0 = await registry.register({ + space: aliceSpace, + blob: blob0, + cause: cause0, + }) + assert.ok(aliceReg0.ok) + + // Add bob allocations + const bobReg = await registry.register({ + space: bobSpace, + blob: blob1, + cause: cause1, + }) + assert.ok(bobReg.ok) + + const entriesAlice1 = await registry.entries(aliceSpace) + assert.ok(entriesAlice1.ok) + assert.equal(entriesAlice1.ok?.size, 1) + assert.equal(entriesAlice1.ok?.results.length, 1) + assert.ok( + equals( + blob0.digest.bytes, + entriesAlice1.ok?.results[0].blob.digest.bytes || new Uint8Array() + ) + ) + + // Add bobs data to alice's space + const cause2 = await randomCID() + const aliceReg1 = await registry.register({ + space: aliceSpace, + blob: blob1, + cause: cause2, + }) + assert.ok(aliceReg1.ok) + + const entriesAlice2 = await registry.entries(aliceSpace) + assert.ok(entriesAlice2.ok) + assert.equal(entriesAlice2.ok?.size, 2) + assert.equal(entriesAlice2.ok?.results.length, 2) + assert.ok( + entriesAlice2.ok?.results.some((res) => + equals(res.blob.digest.bytes, blob0.digest.bytes) + ) + ) + assert.ok( + entriesAlice2.ok?.results.some((res) => + equals(res.blob.digest.bytes, blob1.digest.bytes) + ) + ) + }, + 'should fail to deregister non existent blob': async (assert, context) => { + const { spaceDid: space } = await registerSpace(alice, context) + const { registry } = context + const data = new Uint8Array([11, 22, 34, 44, 55]) + const digest = await sha256.digest(data) + const cause = await randomCID() + const dereg = await registry.deregister({space, digest, cause}) + assert.ok(dereg.error) + assert.equal(dereg.error?.name, EntryNotFound.name) + }, + 'should deregister a blob': async (assert, context) => { + const { spaceDid: space } = await registerSpace(alice, context) + const { registry } = context + const data = new Uint8Array([11, 22, 34, 44, 55]) + const digest = await sha256.digest(data) + const blob = { digest: digest, size: data.length } + const cause = await randomCID() + + const reg = await registry.register({ space, blob, cause }) + assert.ok(reg.ok) + + const find0 = await registry.find(space, digest) + assert.ok(find0.ok) + + const deregCause = await randomCID() + const dereg = await registry.deregister({space, digest, cause: deregCause}) + assert.ok(dereg.ok) + + const find1 = await registry.find(space, digest) + assert.ok(find1.error) + assert.equal(find1.error?.name, EntryNotFound.name) + }, +} diff --git a/packages/upload-api/test/storage/blob-registry.js b/packages/upload-api/test/storage/blob-registry.js new file mode 100644 index 000000000..ba324de70 --- /dev/null +++ b/packages/upload-api/test/storage/blob-registry.js @@ -0,0 +1,77 @@ +import * as API from '../../src/types.js' +import { ok, error } from '@ucanto/core' +import { equals } from 'multiformats/bytes' +import { EntryExists, EntryNotFound } from '../../src/blob.js' + +/** @implements {API.BlobAPI.Registry} */ +export class Registry { + constructor() { + /** @type {Map} */ + this.data = new Map() + } + + /** @type {API.BlobAPI.Registry['register']} */ + async register({ space, cause, blob }) { + const entries = this.data.get(space) ?? [] + if (entries.some((e) => equals(e.blob.digest.bytes, blob.digest.bytes))) { + return error(new EntryExists()) + } + this.data.set(space, [{ blob, cause, insertedAt: new Date() }, ...entries]) + return ok({}) + } + + /** @type {API.BlobAPI.Registry['find']} */ + async find(space, digest) { + const entries = this.data.get(space) ?? [] + const entry = entries.find((e) => equals(e.blob.digest.bytes, digest.bytes)) + if (!entry) return error(new EntryNotFound()) + return ok(entry) + } + + /** @type {API.BlobAPI.Registry['deregister']} */ + async deregister({space, digest, cause}) { + const entries = this.data.get(space) ?? [] + const entry = entries.find((e) => equals(e.blob.digest.bytes, digest.bytes)) + if (!entry) return error(new EntryNotFound()) + this.data.set( + space, + entries.filter((e) => e !== entry) + ) + return ok({}) + } + + /** @type {API.BlobAPI.Registry['entries']} */ + async entries(space, options) { + const entries = this.data.get(space) ?? [] + const { cursor = '0', size = entries.length } = options ?? {} + const offset = parseInt(cursor, 10) + const items = entries.slice(offset) + + const matches = [...items.entries()].slice(0, size) + + if (matches.length === 0) { + return ok({ size: 0, results: [] }) + } + + const first = matches[0] + const last = matches[matches.length - 1] + + const start = first[0] || 0 + const end = last[0] || 0 + const values = matches.map(([_, item]) => item) + + const [before, after, results] = [ + `${start + offset}`, + `${end + 1 + offset}`, + values, + ] + + return ok({ + size: values.length, + before, + after, + cursor: after, + results, + }) + } +} diff --git a/packages/upload-api/test/storage/blob-registry.spec.js b/packages/upload-api/test/storage/blob-registry.spec.js new file mode 100644 index 000000000..fefebbfd4 --- /dev/null +++ b/packages/upload-api/test/storage/blob-registry.spec.js @@ -0,0 +1,3 @@ +import * as BlobRegistry from './blob-registry-tests.js' +import { test } from '../test.js' +test({ 'in memory blob registry': BlobRegistry.test }) diff --git a/packages/upload-api/test/storage/blobs-storage-tests.js b/packages/upload-api/test/storage/blobs-storage-tests.js deleted file mode 100644 index 9596533ef..000000000 --- a/packages/upload-api/test/storage/blobs-storage-tests.js +++ /dev/null @@ -1,74 +0,0 @@ -import * as API from '../../src/types.js' -import { sha256 } from 'multiformats/hashes/sha2' -import * as Result from '../helpers/result.js' -import { equals } from 'multiformats/bytes' - -/** - * @type {API.Tests} - */ -export const test = { - 'should create valid presigned URL for blobs that can be used to write': - async (assert, context) => { - const blobsStorage = context.blobsStorage - const data = new Uint8Array([11, 22, 34, 44, 55]) - const multihash0 = await sha256.digest(data) - const digest = multihash0.bytes - const size = data.byteLength - const expiresIn = 60 * 60 * 24 // 1 day - const blob = { - digest: digest, - size: size, - } - const createUploadUrl = await blobsStorage.createUploadUrl( - multihash0, - blob.size, - expiresIn - ) - if (!createUploadUrl.ok) { - throw new Error('should create presigned url') - } - - assert.ok(createUploadUrl.ok.headers['content-length']) - assert.ok(createUploadUrl.ok.headers['x-amz-checksum-sha256']) - - // Store the blob to the address - const goodPut = await fetch(createUploadUrl.ok.url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: createUploadUrl.ok.headers, - }) - assert.equal(goodPut.status, 200, await goodPut.text()) - - // check it exists - const hasBlob = await blobsStorage.has(multihash0) - assert.ok(hasBlob.ok) - }, - - 'should create valid download URL for blobs that can be used to read': async ( - assert, - { blobsStorage } - ) => { - const data = new Uint8Array([11, 22, 34, 44, 55]) - const digest = await sha256.digest(data) - const expires = 60 * 60 * 24 // 1 day - - const upload = Result.unwrap( - await blobsStorage.createUploadUrl(digest, data.length, expires) - ) - - await fetch(upload.url, { - method: 'PUT', - mode: 'cors', - body: data, - headers: upload.headers, - }) - - const downloadUrl = Result.unwrap( - await blobsStorage.createDownloadUrl(digest) - ) - - const res = await fetch(downloadUrl) - assert.ok(equals(new Uint8Array(await res.arrayBuffer()), data)) - }, -} diff --git a/packages/upload-api/test/storage/blobs-storage.js b/packages/upload-api/test/storage/blobs-storage.js deleted file mode 100644 index f1f7489dd..000000000 --- a/packages/upload-api/test/storage/blobs-storage.js +++ /dev/null @@ -1,213 +0,0 @@ -import * as Types from '../../src/types.js' -import { base64pad } from 'multiformats/bases/base64' -import { SigV4 } from '@web3-storage/sigv4' -import { base58btc } from 'multiformats/bases/base58' -import { sha256 } from 'multiformats/hashes/sha2' -import { ok, error } from '@ucanto/core' -import { BlobNotFound } from '../../src/blob/lib.js' - -/** @param {Types.MultihashDigest} digest */ -const contentKey = (digest) => { - const encodedMultihash = base58btc.encode(digest.bytes) - return `${encodedMultihash}/${encodedMultihash}.blob` -} - -/** - * @implements {Types.BlobsStorage} - * @implements {Types.BlobRetriever} - */ -export class BlobsStorage { - /** - * @param {Types.CarStoreBucketOptions & {http?: import('http')}} options - */ - static async activate({ http, ...options } = {}) { - const content = new Map() - if (http) { - const server = http.createServer(async (request, response) => { - const { pathname } = new URL(request.url || '/', url) - if (request.method === 'PUT') { - const buffer = new Uint8Array( - parseInt(request.headers['content-length'] || '0') - ) - let offset = 0 - for await (const chunk of request) { - buffer.set(chunk, offset) - offset += chunk.length - } - const hash = await sha256.digest(buffer) - const checksum = base64pad.baseEncode(hash.digest) - - if (checksum !== request.headers['x-amz-checksum-sha256']) { - response.writeHead(400, `checksum mismatch`) - } else { - content.set(pathname, buffer) - response.writeHead(200) - } - } else if (request.method === 'GET') { - const data = content.get(pathname) - if (data) { - response.writeHead(200) - response.write(data) - } else { - response.writeHead(404) - } - } else { - response.writeHead(405) - } - - response.end() - // otherwise it keep connection lingering - response.destroy() - }) - await new Promise((resolve) => server.listen(resolve)) - - // @ts-ignore - this is actually what it returns on http - const port = server.address().port - const url = new URL(`http://localhost:${port}`) - - return new BlobsStorage({ - ...options, - content, - url, - server, - }) - } else { - return new BlobsStorage({ - ...options, - content, - url: new URL(`http://localhost:8989`), - }) - } - } - - /** - * @returns {Promise} - */ - async deactivate() { - const { server } = this - if (server) { - await new Promise((resolve, reject) => { - // does not exist in node 16 - if (typeof server.closeAllConnections === 'function') { - server.closeAllConnections() - } - - server.close((error) => { - if (error) { - reject(error) - } else { - resolve(undefined) - } - }) - }) - } - } - - /** - * @param {Types.CarStoreBucketOptions & { server?: import('http').Server, url: URL, content: Map }} options - */ - constructor({ - content, - url, - server, - accessKeyId = 'id', - secretAccessKey = 'secret', - bucket = 'my-bucket', - region = 'eu-central-1', - }) { - this.server = server - this.baseURL = url - this.accessKeyId = accessKeyId - this.secretAccessKey = secretAccessKey - this.bucket = bucket - this.region = region - this.content = content - } - - /** @param {Types.MultihashDigest} digest */ - #bucketPath(digest) { - return `/${this.bucket}/${contentKey(digest)}` - } - - /** @param {Types.MultihashDigest} digest */ - async has(digest) { - return ok(this.content.has(this.#bucketPath(digest))) - } - - /** @param {Types.MultihashDigest} digest */ - async stream(digest) { - const key = this.#bucketPath(digest) - if (!this.server) { - const url = new URL(key, this.baseURL) - const res = await fetch(url.toString()) - if (res.status === 404) return error(new BlobNotFound(digest)) - if (!res.ok || !res.body) { - throw new Error( - `serverless blob storage failed to fetch from: ${url} status: ${res.status}` - ) - } - return ok(res.body) - } - - const bytes = this.content.get(key) - if (!bytes) return error(new BlobNotFound(digest)) - - return ok( - new ReadableStream({ - pull(controller) { - controller.enqueue(bytes) - controller.close() - }, - }) - ) - } - - /** - * @param {Types.MultihashDigest} digest - * @param {number} size - * @param {number} expiresIn - */ - async createUploadUrl(digest, size, expiresIn) { - const { bucket, accessKeyId, secretAccessKey, region, baseURL } = this - - // sigv4 - const sig = new SigV4({ - accessKeyId, - secretAccessKey, - region, - }) - - const checksum = base64pad.baseEncode(digest.digest) - const { search, hash } = sig.sign({ - key: contentKey(digest), - checksum, - bucket, - expires: expiresIn, - }) - - const url = new URL(baseURL) - url.search = search - url.pathname = this.#bucketPath(digest) - url.hash = hash - url.searchParams.set( - 'X-Amz-SignedHeaders', - ['content-length', 'host', 'x-amz-checksum-sha256'].join(';') - ) - - return { - ok: { - url, - headers: { - 'x-amz-checksum-sha256': checksum, - 'content-length': String(size), - }, - }, - } - } - - /** @param {Types.MultihashDigest} digest */ - async createDownloadUrl(digest) { - const url = new URL(this.#bucketPath(digest), this.baseURL) - return ok(/** @type {Types.URI} */ (url.toString())) - } -} diff --git a/packages/upload-api/test/storage/blobs-storage.spec.js b/packages/upload-api/test/storage/blobs-storage.spec.js deleted file mode 100644 index 33682e9d4..000000000 --- a/packages/upload-api/test/storage/blobs-storage.spec.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as BlobsStorage from './blobs-storage-tests.js' -import { test } from '../test.js' -test({ 'in memory blobs storage': BlobsStorage.test }) diff --git a/packages/upload-api/test/storage/car-store-bucket.js b/packages/upload-api/test/storage/car-store-bucket.js deleted file mode 100644 index f0db90b67..000000000 --- a/packages/upload-api/test/storage/car-store-bucket.js +++ /dev/null @@ -1,160 +0,0 @@ -import * as API from '../../src/types.js' -import { base64pad } from 'multiformats/bases/base64' -import { SigV4 } from '@web3-storage/sigv4' -import { sha256 } from 'multiformats/hashes/sha2' - -/** - * @implements {API.CarStoreBucket} - */ -export class CarStoreBucket { - /** - * @param {API.CarStoreBucketOptions & {http?: import('http')}} options - */ - static async activate({ http, ...options } = {}) { - const content = new Map() - if (http) { - const server = http.createServer(async (request, response) => { - if (request.method === 'PUT') { - const buffer = new Uint8Array( - parseInt(request.headers['content-length'] || '0') - ) - let offset = 0 - - for await (const chunk of request) { - buffer.set(chunk, offset) - offset += chunk.length - } - - const hash = await sha256.digest(buffer) - const checksum = base64pad.baseEncode(hash.digest) - - if (checksum !== request.headers['x-amz-checksum-sha256']) { - response.writeHead(400, `checksum mismatch`) - } else { - const { pathname } = new URL(request.url || '/', url) - content.set(pathname, buffer) - response.writeHead(200) - } - } else { - response.writeHead(405) - } - - response.end() - // otherwise it keep connection lingering - response.destroy() - }) - await new Promise((resolve) => server.listen(resolve)) - - // @ts-ignore - this is actually what it returns on http - const port = server.address().port - const url = new URL(`http://localhost:${port}`) - - return new CarStoreBucket({ - ...options, - content, - url, - server, - }) - } else { - return new CarStoreBucket({ - ...options, - content, - url: new URL(`http://localhost:8989`), - }) - } - } - - /** - * @param {API.CarStoreBucketOptions & { server?: import('http').Server, url: URL, content: Map }} options - */ - constructor({ - content, - url, - server, - accessKeyId = 'id', - secretAccessKey = 'secret', - bucket = 'my-bucket', - region = 'eu-central-1', - expires, - }) { - this.server = server - this.baseURL = url - this.accessKeyId = accessKeyId - this.secretAccessKey = secretAccessKey - this.bucket = bucket - this.region = region - this.expires = expires - this.content = content - } - - /** - * @returns {Promise} - */ - async deactivate() { - const { server } = this - if (server) { - await new Promise((resolve, reject) => { - // does not exist in node 16 - if (typeof server.closeAllConnections === 'function') { - server.closeAllConnections() - } - - server.close((error) => { - if (error) { - reject(error) - } else { - resolve(undefined) - } - }) - }) - } - } - - /** - * - * @param {API.UnknownLink} link - */ - async has(link) { - return this.content.has(`/${this.bucket}/${link}/${link}.car`) - } - - /** - * @param {API.UnknownLink} link - * @param {number} size - */ - async createUploadUrl(link, size) { - const { bucket, expires, accessKeyId, secretAccessKey, region, baseURL } = - this - // sigv4 - const sig = new SigV4({ - accessKeyId, - secretAccessKey, - region, - }) - - const checksum = base64pad.baseEncode(link.multihash.digest) - const { pathname, search, hash } = sig.sign({ - key: `${link}/${link}.car`, - checksum, - bucket, - expires, - }) - - const url = new URL(baseURL) - url.search = search - url.pathname = `/${bucket}${pathname}` - url.hash = hash - url.searchParams.set( - 'X-Amz-SignedHeaders', - ['content-length', 'host', 'x-amz-checksum-sha256'].join(';') - ) - - return { - url, - headers: { - 'x-amz-checksum-sha256': checksum, - 'content-length': String(size), - }, - } - } -} diff --git a/packages/upload-api/test/storage/index.js b/packages/upload-api/test/storage/index.js index c4aab381a..d2bcbba87 100644 --- a/packages/upload-api/test/storage/index.js +++ b/packages/upload-api/test/storage/index.js @@ -1,7 +1,4 @@ -import { AllocationsStorage } from './allocations-storage.js' -import { BlobsStorage } from './blobs-storage.js' -import { CarStoreBucket } from './car-store-bucket.js' -import { StoreTable } from './store-table.js' +import { Registry as BlobRegistry } from './blob-registry.js' import { UploadTable } from './upload-table.js' import { ProvisionsStorage } from './provisions-storage.js' import { DelegationsStorage } from './delegations-storage.js' @@ -20,14 +17,11 @@ import * as AgentStore from './agent-store.js' * @param {{fail(error:unknown): unknown}} [options.assert] */ export async function getServiceStorageImplementations(options) { - const storeTable = new StoreTable() - const allocationsStorage = new AllocationsStorage() + const registry = new BlobRegistry() const uploadTable = new UploadTable() - const blobsStorage = await BlobsStorage.activate(options) - const carStoreBucket = await CarStoreBucket.activate(options) const revocationsStorage = new RevocationsStorage() const plansStorage = new PlansStorage() - const usageStorage = new UsageStorage(storeTable, allocationsStorage) + const usageStorage = new UsageStorage(registry) const provisionsStorage = new ProvisionsStorage(options.providers) const subscriptionsStorage = new SubscriptionsStorage(provisionsStorage) const delegationsStorage = new DelegationsStorage() @@ -35,12 +29,8 @@ export async function getServiceStorageImplementations(options) { const agentStore = AgentStore.memory() return { - storeTable, - allocationsStorage, + registry, uploadTable, - blobsStorage, - blobRetriever: blobsStorage, - carStoreBucket, revocationsStorage, plansStorage, usageStorage, diff --git a/packages/upload-api/test/storage/plans-storage-tests.js b/packages/upload-api/test/storage/plans-storage-tests.js index ac403102e..f806d1311 100644 --- a/packages/upload-api/test/storage/plans-storage-tests.js +++ b/packages/upload-api/test/storage/plans-storage-tests.js @@ -2,7 +2,7 @@ import * as API from '../../src/types.js' const account = 'did:mailto:example.com:alice' const billingID = 'stripe:abc123' -const product = 'did:web:free.web3.storage' +const product = 'did:web:free.storacha.network' /** * @type {API.Tests} @@ -52,7 +52,7 @@ export const test = { const getResult = await storage.get(account) assert.equal(getResult.ok?.product, product) - const newProduct = 'did:web:expensive.web3.storage' + const newProduct = 'did:web:expensive.storacha.network' const setResult = await storage.set(account, newProduct) diff --git a/packages/upload-api/test/storage/provisions-storage-tests.js b/packages/upload-api/test/storage/provisions-storage-tests.js index e9efd4d6a..02c54da8c 100644 --- a/packages/upload-api/test/storage/provisions-storage-tests.js +++ b/packages/upload-api/test/storage/provisions-storage-tests.js @@ -1,7 +1,7 @@ import * as API from '../../src/types.js' import * as Types from '../types.js' import * as principal from '@ucanto/principal' -import { Provider } from '@web3-storage/capabilities' +import { Provider } from '@storacha/capabilities' /** * @type {API.Tests} @@ -14,7 +14,7 @@ export const test = { const issuerKey = await principal.ed25519.generate() const issuerDID = 'did:mailto:example.com:foo' const issuer = issuerKey.withDID(issuerDID) - const provider = 'did:web:web3.storage:providers:w3up-alpha' + const provider = 'did:web:storacha.network:providers:w3up-alpha' const invocation = await Provider.add .invoke({ issuer, diff --git a/packages/upload-api/test/storage/provisions-storage.js b/packages/upload-api/test/storage/provisions-storage.js index 78f38426e..169513b10 100644 --- a/packages/upload-api/test/storage/provisions-storage.js +++ b/packages/upload-api/test/storage/provisions-storage.js @@ -16,7 +16,7 @@ export class ProvisionsStorage { * * @param {Array} providers */ - constructor(providers = ['did:web:test.web3.storage']) { + constructor(providers = ['did:web:test.upload.storacha.network']) { /** * @type {Record} */ diff --git a/packages/upload-api/test/storage/store-table.js b/packages/upload-api/test/storage/store-table.js deleted file mode 100644 index 3cb197048..000000000 --- a/packages/upload-api/test/storage/store-table.js +++ /dev/null @@ -1,134 +0,0 @@ -import * as API from '../../src/types.js' - -/** - * @implements {API.StoreTable} - */ -export class StoreTable { - constructor() { - /** @type {(API.StoreAddInput & API.StoreListItem)[]} */ - this.items = [] - } - - /** - * @param {API.StoreAddInput} input - * @returns {ReturnType} - */ - async insert({ space, issuer, invocation, ...output }) { - if ( - this.items.some((i) => i.space === space && i.link.equals(output.link)) - ) { - return { - error: { name: 'RecordKeyConflict', message: 'record key conflict' }, - } - } - this.items.unshift({ - space, - issuer, - invocation, - ...output, - insertedAt: new Date().toISOString(), - }) - return { ok: output } - } - - /** - * @param {API.UnknownLink} link - * @returns {ReturnType} - */ - async inspect(link) { - const items = this.items.filter((item) => item.link.equals(link)) - return { - ok: { - spaces: items.map((item) => ({ - did: item.space, - insertedAt: item.insertedAt, - })), - }, - } - } - - /** - * @param {API.DID} space - * @param {API.UnknownLink} link - * @returns {ReturnType} - */ - async get(space, link) { - const item = this.items.find( - (i) => i.space === space && i.link.equals(link) - ) - if (!item) { - return { error: { name: 'RecordNotFound', message: 'record not found' } } - } - return { ok: item } - } - - /** - * @param {API.DID} space - * @param {API.UnknownLink} link - * @returns {ReturnType} - */ - async exists(space, link) { - const item = this.items.find( - (i) => i.space === space && i.link.equals(link) - ) - return { ok: !!item } - } - - /** - * @param {API.DID} space - * @param {API.UnknownLink} link - * @returns {ReturnType} - */ - async remove(space, link) { - const item = this.items.find( - (i) => i.space === space && i.link.equals(link) - ) - if (!item) { - return { error: { name: 'RecordNotFound', message: 'record not found' } } - } - this.items = this.items.filter((i) => i !== item) - return { ok: item } - } - - /** - * @param {API.DID} space - * @param {API.ListOptions} options - * @returns {ReturnType} - */ - async list( - space, - { cursor = '0', pre = false, size = this.items.length } = {} - ) { - const offset = parseInt(cursor, 10) - const items = pre ? this.items.slice(0, offset) : this.items.slice(offset) - - const matches = [...items.entries()] - .filter(([n, item]) => item.space === space) - .slice(0, size) - - if (matches.length === 0) { - return { ok: { size: 0, results: [] } } - } - - const first = matches[0] - const last = matches[matches.length - 1] - - const start = first[0] || 0 - const end = last[0] || 0 - const values = matches.map(([_, item]) => item) - - const [before, after, results] = pre - ? [`${start}`, `${end + 1}`, values] - : [`${start + offset}`, `${end + 1 + offset}`, values] - - return { - ok: { - size: values.length, - before, - after, - cursor: after, - results, - }, - } - } -} diff --git a/packages/upload-api/test/storage/upload-table.js b/packages/upload-api/test/storage/upload-table.js index 6fe9afb4f..811c2d7e8 100644 --- a/packages/upload-api/test/storage/upload-table.js +++ b/packages/upload-api/test/storage/upload-table.js @@ -30,7 +30,7 @@ export class UploadTable { * @param {API.UploadAddInput} input * @returns {ReturnType} */ - async upsert({ space, issuer, invocation, root, shards = [] }) { + async upsert({ space, issuer, cause, root, shards = [] }) { const time = new Date().toISOString() const item = this.items.find( (item) => item.space === space && item.root.toString() === root.toString() @@ -52,7 +52,7 @@ export class UploadTable { this.items.unshift({ space, issuer, - invocation, + cause, root, shards, insertedAt: time, diff --git a/packages/upload-api/test/storage/usage-storage.js b/packages/upload-api/test/storage/usage-storage.js index 8e571f87b..9c8e5e332 100644 --- a/packages/upload-api/test/storage/usage-storage.js +++ b/packages/upload-api/test/storage/usage-storage.js @@ -3,12 +3,10 @@ /** @implements {UsageStore} */ export class UsageStorage { /** - * @param {import('./store-table.js').StoreTable} storeTable - * @param {import('./allocations-storage.js').AllocationsStorage} allocationsStorage + * @param {import('./blob-registry.js').Registry} blobRegistry */ - constructor(storeTable, allocationsStorage) { - this.storeTable = storeTable - this.allocationsStorage = allocationsStorage + constructor(blobRegistry) { + this.blobRegistry = blobRegistry /** * @type {Record} */ @@ -16,16 +14,9 @@ export class UsageStorage { } get items() { - return [ - ...this.storeTable.items.map((item) => ({ - ...item, - cause: item.invocation, - })), - ...this.allocationsStorage.items.map((item) => ({ - ...item, - size: item.blob.size, - })), - ] + return [...this.blobRegistry.data.entries()].flatMap(([space, entries]) => + entries.map((e) => ({ space, size: e.blob.size, ...e })) + ) } /** @@ -62,7 +53,7 @@ export class UsageStorage { return { cause: /** @type {import('../types.js').Link} */ (item.cause), delta: item.size, - receiptAt: item.insertedAt, + receiptAt: item.insertedAt.toISOString(), } }), }, diff --git a/packages/upload-api/test/util.js b/packages/upload-api/test/util.js index 44c47a2cd..9c8871624 100644 --- a/packages/upload-api/test/util.js +++ b/packages/upload-api/test/util.js @@ -29,7 +29,7 @@ export const service = ed25519 .parse( 'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8=' ) - .withDID('did:web:test.web3.storage') + .withDID('did:web:test.upload.storacha.network') /** * @param {import('@ucanto/interface').Principal} audience @@ -61,7 +61,7 @@ export const registerSpace = async (audience, context, username = 'alice') => { channel: createServer(context), }) const account = Absentee.from({ - id: `did:mailto:test.web3.storage:${username}`, + id: `did:mailto:test.storacha.network:${username}`, }) const provisionResult = await provisionProvider({ @@ -99,7 +99,6 @@ export async function randomCAR(size) { const hash = await sha256.digest(bytes) const root = CID.create(1, raw.code, hash) - // @ts-expect-error old multiformats in @ipld/car const { writer, out } = CarWriter.create(root) writer.put({ cid: root, bytes }) writer.close() diff --git a/packages/upload-client/CHANGELOG.md b/packages/upload-client/CHANGELOG.md index 18a5a58fa..803e29bcd 100644 --- a/packages/upload-client/CHANGELOG.md +++ b/packages/upload-client/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## [1.0.4](https://github.com/storacha/upload-service/compare/upload-client-v1.0.3...upload-client-v1.0.4) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.0.3](https://github.com/storacha/upload-service/compare/upload-client-v1.0.2...upload-client-v1.0.3) (2025-01-16) + + +### Other Changes + +* sync with w3up repo ([#119](https://github.com/storacha/upload-service/issues/119)) ([d86e52c](https://github.com/storacha/upload-service/commit/d86e52cfdb58c38a8499aaed03260f683eceae44)) + +## [1.0.2](https://github.com/storacha/upload-service/compare/upload-client-v1.0.1...upload-client-v1.0.2) (2024-12-19) + + +### Fixes + +* compatibility with legacy w3up client ([#59](https://github.com/storacha/upload-service/issues/59)) ([7185046](https://github.com/storacha/upload-service/commit/7185046e3186bef9b4f56f9e6c1c94a0c576fc53)) +* jsdoc ([5506c11](https://github.com/storacha/upload-service/commit/5506c11eeda8351dd21f6fff339057e69813eab2)) +* overflow slices ([#1595](https://github.com/storacha/upload-service/issues/1595)) ([949b84a](https://github.com/storacha/upload-service/commit/949b84ac808e6147178a4de693607ebd409388b4)) +* retry when PUT request fails ([#1601](https://github.com/storacha/upload-service/issues/1601)) ([7836dc4](https://github.com/storacha/upload-service/commit/7836dc46054cc328d54cb0833e394e263f11fb69)) +* thanks prettier ([11e34b4](https://github.com/storacha/upload-service/commit/11e34b40af2485757f8ba2056c08a100677dc393)) +* trigger release ([f0f9a56](https://github.com/storacha/upload-service/commit/f0f9a56bb28bc50e33845f07c859cd209562a338)) + + +### Other Changes + +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([aec53e7](https://github.com/storacha/upload-service/commit/aec53e714ea581421e1c55a6e282b765f5badaaa)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) +* prettier ([40ebc05](https://github.com/storacha/upload-service/commit/40ebc052b0b2d0d789b254ce0e4ec6e7687f7e41)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/upload-client-v1.0.0...upload-client-v1.0.1) (2024-11-12) + + +### Fixes + +* consume response body ([9d3659e](https://github.com/storacha/upload-service/commit/9d3659e28bf4c29e6a613e1cb42751e4f13dff41)) + +## 1.0.0 (2024-11-05) + + +### Features + +* remove store protocol ([d59ec88](https://github.com/storacha/upload-service/commit/d59ec883ace9c3f084772f9520b6df81cc13b7af)) +* remove store protocol ([#13](https://github.com/storacha/upload-service/issues/13)) ([0028049](https://github.com/storacha/upload-service/commit/0028049f0bd3fcb816968687694c4611a5147148)) + ## [17.1.0](https://github.com/storacha/w3up/compare/upload-client-v17.0.1...upload-client-v17.1.0) (2024-10-24) diff --git a/packages/upload-client/README.md b/packages/upload-client/README.md index 35263161b..9ed800267 100644 --- a/packages/upload-client/README.md +++ b/packages/upload-client/README.md @@ -1,20 +1,20 @@ -


web3.storage

-

The upload client for https://web3.storage

+


storacha.network

+

The upload client for https://storacha.network

## About -The `@web3-storage/upload-client` package provides the "low level" client API for uploading data to [web3.storage](https://web3.storage) using the w3up platform. +The `@storacha/upload-client` package provides the "low level" client API for uploading data to [storacha.network](https://storacha.network) using the w3up platform. -Most users will be better served by the higher-level [`@web3-storage/w3up-client` package](https://github.com/storacha/w3up-client), which presents a simpler API and supports creating agents and registering spaces. +Most users will be better served by the higher-level [`@storacha/client` package](https://github.com/storacha/upload-service/tree/main/packages/w3up-client), which presents a simpler API and supports creating agents and registering spaces. -If you are using this package directly instead of `w3up-client`, you will also need to use the [`@web3-storage/access` client](https://github.com/storacha/w3up/tree/main/packages/access-client) for agent and space management. The `@web3-storage/capabilities` package referenced in the examples below is a transitive dependency of both `@web3-storage/upload-client` and `@web3-storage/access`, so you shouldn't need to install it explicitly. +If you are using this package directly instead of `w3up-client`, you will also need to use the [`@storacha/access` client](https://github.com/storacha/upload-service/tree/main/packages/access-client) for agent and space management. The `@storacha/capabilities` package referenced in the examples below is a transitive dependency of both `@storacha/upload-client` and `@storacha/access`, so you shouldn't need to install it explicitly. ## Install Install the package using npm: ```bash -npm install @web3-storage/upload-client +npm install @storacha/upload-client ``` ## Usage @@ -30,9 +30,9 @@ An agent provides: 3. Proof showing your `issuer` has been delegated capabilities to store data and register uploads to the "space" (`proofs`). ```js -import { Agent } from '@web3-storage/access' -import { store } from '@web3-storage/capabilities/store' -import { upload } from '@web3-storage/capabilities/upload' +import { Agent } from '@storacha/access' +import { store } from '@storacha/capabilities/store' +import { upload } from '@storacha/capabilities/upload' const agent = await Agent.create() @@ -47,7 +47,7 @@ const conf = { } ``` -See the [`@web3-storage/access` docs](https://web3-storage.github.io/w3up/modules/_web3_storage_access.html) for more about creating and registering spaces. +See the [`@storacha/access` docs](https://web3-storage.github.io/w3up/modules/_web3_storage_access.html) for more about creating and registering spaces. ### Uploading files @@ -56,13 +56,13 @@ Once you have the `issuer`, `with` and `proofs`, you can upload a directory of f You can get your list of Files from a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file) element in the browser or using [`files-from-path`](https://npm.im/files-from-path) in Node.js ```js -import { uploadFile } from '@web3-storage/upload-client' +import { uploadFile } from '@storacha/upload-client' const cid = await uploadFile(conf, new Blob(['Hello World!'])) ``` ```js -import { uploadDirectory } from '@web3-storage/upload-client' +import { uploadDirectory } from '@storacha/upload-client' const cid = await uploadDirectory(conf, [ new File(['doc0'], 'doc0.txt'), @@ -77,8 +77,8 @@ const cid = await uploadDirectory(conf, [ The buffering API loads all data into memory so is suitable only for small files. The root data CID is derived from the data before any transfer to the service takes place. ```js -import { UnixFS, CAR, Blob, Index, Upload } from '@web3-storage/upload-client' -import * as BlobIndexUtil from '@web3-storage/blob-index/util' +import { UnixFS, CAR, Blob, Index, Upload } from '@storacha/upload-client' +import * as BlobIndexUtil from '@storacha/blob-index/util' import * as Link from 'multiformats/link' // Encode a file as a DAG, get back a root data CID and a set of blocks @@ -107,8 +107,8 @@ import { Blob, Index, Upload, -} from '@web3-storage/upload-client' -import { ShardedDAGIndex } from '@web3-storage/blob-index' +} from '@storacha/upload-client' +import { ShardedDAGIndex } from '@storacha/blob-index' let rootCID, carCIDs const shardIndexes = [] @@ -536,8 +536,8 @@ The function may be called multiple times with different requested capabilities. Example: ```js -import { Agent } from '@web3-storage/access' -import * as Space from '@web3-storage/access/space' +import { Agent } from '@storacha/access' +import * as Space from '@storacha/access/space' const agent = await Agent.create() const space = await Space.generate({ name: 'myspace' }) @@ -571,8 +571,8 @@ More information: [`CARMetadata`](#carmetadata) ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/license.md) +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/license.md) diff --git a/packages/upload-client/package.json b/packages/upload-client/package.json index 8ab9cca3a..c3284d9fc 100644 --- a/packages/upload-client/package.json +++ b/packages/upload-client/package.json @@ -1,11 +1,11 @@ { - "name": "@web3-storage/upload-client", - "version": "17.1.0", - "description": "The web3.storage upload client", - "homepage": "https://web3.storage", + "name": "@storacha/upload-client", + "version": "1.0.4", + "description": "The storacha.network upload client", + "homepage": "https://storacha.network", "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/upload-client" }, "author": "Alan Shaw", @@ -82,29 +82,29 @@ "dependencies": { "@ipld/car": "^5.2.2", "@ipld/dag-cbor": "^9.0.6", - "@ipld/dag-ucan": "^3.4.0", - "@ipld/unixfs": "^2.1.1", + "@ipld/dag-ucan": "^3.4.5", + "@ipld/unixfs": "^3.0.0", + "@storacha/blob-index": "workspace:^", + "@storacha/capabilities": "workspace:^", + "@storacha/filecoin-client": "workspace:^", "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", "@ucanto/transport": "^9.1.1", - "@web3-storage/blob-index": "workspace:^", - "@web3-storage/capabilities": "workspace:^", "@web3-storage/data-segment": "^5.1.0", - "@web3-storage/filecoin-client": "workspace:^", "ipfs-utils": "^9.0.14", - "multiformats": "^12.1.2", + "multiformats": "^13.3.1", "p-retry": "^5.1.2", "varint": "^6.0.0" }, "devDependencies": { + "@storacha/eslint-config": "workspace:^", "@types/assert": "^1.5.6", "@types/mocha": "^10.0.1", "@types/varint": "^6.0.1", - "@ucanto/principal": "^9.0.1", - "@ucanto/server": "^10.0.0", - "@web3-storage/content-claims": "^5.0.0", - "@web3-storage/eslint-config-w3up": "workspace:^", + "@ucanto/principal": "^9.0.2", + "@ucanto/server": "^10.1.0", + "@web3-storage/content-claims": "^5.1.3", "assert": "^2.0.0", "blockstore-core": "^3.0.0", "c8": "^7.13.0", @@ -117,7 +117,7 @@ }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -141,7 +141,7 @@ "@types/*", "assert", "c8", - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ] } } diff --git a/packages/upload-client/src/blob/add.js b/packages/upload-client/src/blob/add.js index 493c4a4f3..f60fccf34 100644 --- a/packages/upload-client/src/blob/add.js +++ b/packages/upload-client/src/blob/add.js @@ -1,15 +1,15 @@ import { ed25519 } from '@ucanto/principal' -import { conclude } from '@web3-storage/capabilities/ucan' -import * as UCAN from '@web3-storage/capabilities/ucan' +import * as UCAN from '@storacha/capabilities/ucan' import { Delegation, Receipt } from '@ucanto/core' -import * as W3sBlobCapabilities from '@web3-storage/capabilities/web3.storage/blob' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import * as HTTPCapabilities from '@web3-storage/capabilities/http' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as BlobCapabilities from '@storacha/capabilities/blob' +import * as SpaceBlobCapabilities from '@storacha/capabilities/space/blob' +import * as HTTPCapabilities from '@storacha/capabilities/http' +import { SpaceDID } from '@storacha/capabilities/utils' import retry, { AbortError } from 'p-retry' import { servicePrincipal, connection } from '../service.js' import { REQUEST_RETRIES } from '../constants.js' import { poll } from '../receipts.js' +import { isCloudflareWorkers } from '../runtime.js' /** * @param {string} url @@ -51,7 +51,7 @@ function parseBlobAddReceiptNext(receipt) { // @ts-expect-error read only effect const forkInvocations = receipt.fx.fork const allocateTask = forkInvocations.find( - (fork) => fork.capabilities[0].can === W3sBlobCapabilities.allocate.can + (fork) => fork.capabilities[0].can === BlobCapabilities.allocate.can ) const concludefxs = forkInvocations.filter( (fork) => fork.capabilities[0].can === UCAN.conclude.can @@ -60,7 +60,7 @@ function parseBlobAddReceiptNext(receipt) { (fork) => fork.capabilities[0].can === HTTPCapabilities.put.can ) const acceptTask = forkInvocations.find( - (fork) => fork.capabilities[0].can === W3sBlobCapabilities.accept.can + (fork) => fork.capabilities[0].can === BlobCapabilities.accept.can ) /* c8 ignore next 3 */ @@ -121,7 +121,7 @@ export function createConcludeInvocation(id, serviceDid, receipt) { receiptBlocks.push(block) receiptCids.push(block.cid) } - const concludeAllocatefx = conclude.invoke({ + const concludeAllocatefx = UCAN.conclude.invoke({ issuer: id, audience: serviceDid, with: id.toDIDKey(), @@ -181,7 +181,7 @@ export async function add( const result = await retry( async () => { - return await BlobCapabilities.add + return await SpaceBlobCapabilities.add .invoke({ issuer, /* c8 ignore next */ @@ -200,7 +200,7 @@ export async function add( ) if (!result.out.ok) { - throw new Error(`failed ${BlobCapabilities.add.can} invocation`, { + throw new Error(`failed ${SpaceBlobCapabilities.add.can} invocation`, { cause: result.out.error, }) } @@ -210,7 +210,7 @@ export async function add( const { receipt: allocateReceipt } = nextTasks.allocate /* c8 ignore next 5 */ if (!allocateReceipt.out.ok) { - throw new Error(`failed ${BlobCapabilities.add.can} invocation`, { + throw new Error(`failed ${SpaceBlobCapabilities.add.can} invocation`, { cause: allocateReceipt.out.error, }) } @@ -223,12 +223,12 @@ export async function add( globalThis.fetch.bind(globalThis) let fetchDidCallUploadProgressCb = false - const { status } = await retry( + await retry( async () => { try { const res = await fetchWithUploadProgress(address.url, { method: 'PUT', - mode: 'cors', + ...(!isCloudflareWorkers && { mode: 'cors' }), body: bytes, headers: address.headers, signal: options.signal, @@ -243,10 +243,14 @@ export async function add( // @ts-expect-error - this is needed by recent versions of node - see https://github.com/bluesky-social/atproto/pull/470 for more info duplex: 'half', }) + // do not retry client errors if (res.status >= 400 && res.status < 500) { throw new AbortError(`upload failed: ${res.status}`) } - return res + if (!res.ok) { + throw new Error(`upload failed: ${res.status}`) + } + await res.arrayBuffer() } catch (err) { if (options.signal?.aborted === true) { throw new AbortError('upload aborted') @@ -258,7 +262,6 @@ export async function add( retries: options.retries ?? REQUEST_RETRIES, } ) - if (status !== 200) throw new Error(`upload failed: ${status}`) if (!fetchDidCallUploadProgressCb && options.onUploadProgress) { // the fetch implementation didn't support onUploadProgress @@ -291,9 +294,12 @@ export async function add( ) const ucanConclude = await httpPutConcludeInvocation.execute(conn) if (!ucanConclude.out.ok) { - throw new Error(`failed ${BlobCapabilities.add.can} invocation`, { - cause: result.out.error, - }) + throw new Error( + `failed ${UCAN.conclude.can} for ${HTTPCapabilities.put.can} invocation`, + { + cause: result.out.error, + } + ) } } @@ -301,6 +307,12 @@ export async function add( let { receipt: acceptReceipt } = nextTasks.accept if (!acceptReceipt?.out.ok) { acceptReceipt = await poll(nextTasks.accept.task.link(), options) + /* c8 ignore next 5 */ + if (acceptReceipt.out.error) { + throw new Error(`${BlobCapabilities.accept.can} failure`, { + cause: acceptReceipt.out.error, + }) + } } const blocks = new Map( @@ -320,7 +332,7 @@ export async function add( } /** Returns the ability used by an invocation. */ -export const ability = BlobCapabilities.add.can +export const ability = SpaceBlobCapabilities.add.can /** * Returns required input to the invocation. diff --git a/packages/upload-client/src/blob/get.js b/packages/upload-client/src/blob/get.js index 5287922a1..5282ac5fd 100644 --- a/packages/upload-client/src/blob/get.js +++ b/packages/upload-client/src/blob/get.js @@ -1,5 +1,5 @@ -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' +import { SpaceDID } from '@storacha/capabilities/utils' import { servicePrincipal, connection } from '../service.js' /** diff --git a/packages/upload-client/src/blob/list.js b/packages/upload-client/src/blob/list.js index eaef942d3..b458412fe 100644 --- a/packages/upload-client/src/blob/list.js +++ b/packages/upload-client/src/blob/list.js @@ -1,5 +1,5 @@ -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' +import { SpaceDID } from '@storacha/capabilities/utils' import { servicePrincipal, connection } from '../service.js' /** @@ -19,7 +19,7 @@ import { servicePrincipal, connection } from '../service.js' * * The issuer needs the `blob/list` delegated capability. * @param {import('../types.js').ListRequestOptions} [options] - * @returns {Promise} + * @returns {Promise} */ export async function list( { issuer, with: resource, proofs, audience }, diff --git a/packages/upload-client/src/blob/remove.js b/packages/upload-client/src/blob/remove.js index 6ecb4db10..509f71e23 100644 --- a/packages/upload-client/src/blob/remove.js +++ b/packages/upload-client/src/blob/remove.js @@ -1,5 +1,5 @@ -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' +import { SpaceDID } from '@storacha/capabilities/utils' import { servicePrincipal, connection } from '../service.js' /** diff --git a/packages/upload-client/src/index.js b/packages/upload-client/src/index.js index f560afc81..ef8b707cb 100644 --- a/packages/upload-client/src/index.js +++ b/packages/upload-client/src/index.js @@ -1,9 +1,8 @@ import * as PieceHasher from '@web3-storage/data-segment/multihash' -import { Storefront } from '@web3-storage/filecoin-client' +import { Storefront } from '@storacha/filecoin-client' import * as Link from 'multiformats/link' import * as raw from 'multiformats/codecs/raw' import { sha256 } from 'multiformats/hashes/sha2' -import * as Store from './store.js' import * as Blob from './blob/index.js' import * as BlobAdd from './blob/add.js' import * as Index from './index/index.js' @@ -13,9 +12,9 @@ import * as UploadAdd from './upload/add.js' import * as UnixFS from './unixfs.js' import * as CAR from './car.js' import { ShardingStream, defaultFileComparator } from './sharding.js' -import { indexShardedDAG } from '@web3-storage/blob-index' +import { indexShardedDAG } from '@storacha/blob-index' -export { Blob, Index, Store, Upload, UnixFS, CAR } +export { Blob, Index, Upload, UnixFS, CAR } export * from './sharding.js' export { receiptsEndpoint } from './service.js' export * as Receipt from './receipts.js' @@ -167,7 +166,7 @@ async function uploadBlockStream( let piece if (pieceHasher) { const multihashDigest = await pieceHasher.digest(bytes) - /** @type {import('@web3-storage/capabilities/types').PieceLink} */ + /** @type {import('@storacha/capabilities/types').PieceLink} */ piece = Link.create(raw.code, multihashDigest) const content = Link.create(raw.code, digest) diff --git a/packages/upload-client/src/index/add.js b/packages/upload-client/src/index/add.js index 662040b43..60a6dd1bc 100644 --- a/packages/upload-client/src/index/add.js +++ b/packages/upload-client/src/index/add.js @@ -1,5 +1,5 @@ -import * as IndexCapabilities from '@web3-storage/capabilities/index' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as IndexCapabilities from '@storacha/capabilities/space/index' +import { SpaceDID } from '@storacha/capabilities/utils' import retry from 'p-retry' import { servicePrincipal, connection } from '../service.js' import { REQUEST_RETRIES } from '../constants.js' @@ -25,7 +25,7 @@ import { REQUEST_RETRIES } from '../constants.js' * The issuer needs the `index/add` delegated capability. * @param {import('../types.js').CARLink} index Index to store. * @param {import('../types.js').RequestOptions} [options] - * @returns {Promise} + * @returns {Promise} */ export async function add( { issuer, with: resource, proofs, audience }, diff --git a/packages/upload-client/src/receipts.js b/packages/upload-client/src/receipts.js index 3851a7cc2..22bd49409 100644 --- a/packages/upload-client/src/receipts.js +++ b/packages/upload-client/src/receipts.js @@ -1,6 +1,6 @@ import retry, { AbortError } from 'p-retry' import { CAR } from '@ucanto/transport' -import { receiptsEndpoint } from './service.js' +import { receiptsEndpoint as defaultReceiptsEndpoint } from './service.js' import { REQUEST_RETRIES } from './constants.js' export class ReceiptNotFound extends Error { @@ -77,6 +77,20 @@ export async function poll(taskCid, options = {}) { ) } +/** + * Calculate a receipt endpoint from the URL of a channel, if it has one. + * + * @param {import('@ucanto/interface').Channel>} channel + */ +function receiptEndpointFromChannel(channel) { + if ('url' in channel && channel.url instanceof URL) { + const url = channel.url + return new URL('/receipt/', url.toString()) + } else { + return null + } +} + /** * Get a receipt for an executed task by its CID. * @@ -85,11 +99,14 @@ export async function poll(taskCid, options = {}) { * @returns {Promise>} */ async function get(taskCid, options = {}) { + const channel = options.connection?.channel + const receiptsEndpoint = + options.receiptsEndpoint ?? + (channel && receiptEndpointFromChannel(channel)) ?? + defaultReceiptsEndpoint + // Fetch receipt from endpoint - const url = new URL( - taskCid.toString(), - options.receiptsEndpoint ?? receiptsEndpoint - ) + const url = new URL(taskCid.toString(), receiptsEndpoint) const fetchReceipt = options.fetch ?? globalThis.fetch.bind(globalThis) const workflowResponse = await fetchReceipt(url) /* c8 ignore start */ @@ -107,7 +124,7 @@ async function get(taskCid, options = {}) { headers: {}, }) // Get receipt from the potential multiple receipts in the message - const receipt = agentMessage.receipts.get(taskCid.toString()) + const receipt = agentMessage.receipts.get(`${taskCid}`) if (!receipt) { return { error: new ReceiptMissing(taskCid), diff --git a/packages/upload-client/src/runtime.js b/packages/upload-client/src/runtime.js new file mode 100644 index 000000000..b67c0fb2e --- /dev/null +++ b/packages/upload-client/src/runtime.js @@ -0,0 +1,4 @@ +/* c8 ignore next 3 */ +export const isCloudflareWorkers = + typeof navigator !== 'undefined' && + navigator?.userAgent === 'Cloudflare-Workers' diff --git a/packages/upload-client/src/service.js b/packages/upload-client/src/service.js index 945671a31..ca8f27b8e 100644 --- a/packages/upload-client/src/service.js +++ b/packages/upload-client/src/service.js @@ -2,9 +2,9 @@ import { connect } from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' import * as DID from '@ipld/dag-ucan/did' -export const serviceURL = new URL('https://up.web3.storage') -export const servicePrincipal = DID.parse('did:web:web3.storage') -export const receiptsEndpoint = 'https://up.web3.storage/receipt/' +export const serviceURL = new URL('https://upload.storacha.network') +export const servicePrincipal = DID.parse('did:web:upload.storacha.network') +export const receiptsEndpoint = 'https://upload.storacha.network/receipt/' /** @type {import('@ucanto/interface').ConnectionView} */ export const connection = connect({ diff --git a/packages/upload-client/src/sharding.js b/packages/upload-client/src/sharding.js index 39848f566..ae8c2b786 100644 --- a/packages/upload-client/src/sharding.js +++ b/packages/upload-client/src/sharding.js @@ -1,4 +1,4 @@ -import { DigestMap } from '@web3-storage/blob-index' +import { DigestMap } from '@storacha/blob-index' import { blockEncodingLength, blockHeaderEncodingLength, @@ -105,7 +105,7 @@ export class ShardingStream extends TransformStream { overflowCurrentLength = 0 /** @type {Map} */ const overflowSlices = new DigestMap() - for (const block of blocks) { + for (const block of overflowBlocks) { const overflowBlockHeaderLength = blockHeaderEncodingLength(block) overflowSlices.set(block.cid.multihash, [ headerLength + overflowCurrentLength + overflowBlockHeaderLength, diff --git a/packages/upload-client/src/store.js b/packages/upload-client/src/store.js deleted file mode 100644 index 375221c97..000000000 --- a/packages/upload-client/src/store.js +++ /dev/null @@ -1,303 +0,0 @@ -import { CAR } from '@ucanto/transport' -import * as StoreCapabilities from '@web3-storage/capabilities/store' -import { SpaceDID } from '@web3-storage/capabilities/utils' -import retry, { AbortError } from 'p-retry' -import { servicePrincipal, connection } from './service.js' -import { REQUEST_RETRIES } from './constants.js' - -/** - * - * @param {string} url - * @param {import('./types.js').ProgressFn} handler - */ -function createUploadProgressHandler(url, handler) { - /** - * - * @param {import('./types.js').ProgressStatus} status - */ - function onUploadProgress({ total, loaded, lengthComputable }) { - return handler({ total, loaded, lengthComputable, url }) - } - return onUploadProgress -} - -/** - * Store a DAG encoded as a CAR file. The issuer needs the `store/add` - * delegated capability. - * - * Required delegated capability proofs: `store/add` - * - * @param {import('./types.js').InvocationConfig} conf Configuration - * for the UCAN invocation. An object with `issuer`, `with` and `proofs`. - * - * The `issuer` is the signing authority that is issuing the UCAN - * invocation(s). It is typically the user _agent_. - * - * The `with` is the resource the invocation applies to. It is typically the - * DID of a space. - * - * The `proofs` are a set of capability delegations that prove the issuer - * has the capability to perform the action. - * - * The issuer needs the `store/add` delegated capability. - * @param {Blob|Uint8Array} car CAR file data. - * @param {import('./types.js').RequestOptions} [options] - * @returns {Promise} - */ -export async function add( - { issuer, with: resource, proofs, audience }, - car, - options = {} -) { - // TODO: validate blob contains CAR data - /* c8 ignore next 2 */ - const bytes = - car instanceof Uint8Array ? car : new Uint8Array(await car.arrayBuffer()) - const link = await CAR.codec.link(bytes) - /* c8 ignore next */ - const conn = options.connection ?? connection - const result = await retry( - async () => { - return await StoreCapabilities.add - .invoke({ - issuer, - /* c8 ignore next */ - audience: audience ?? servicePrincipal, - with: SpaceDID.from(resource), - nb: { link, size: bytes.length }, - proofs, - nonce: options.nonce, - }) - .execute(conn) - }, - { - onFailedAttempt: console.warn, - retries: options.retries ?? REQUEST_RETRIES, - } - ) - - if (!result.out.ok) { - throw new Error(`failed ${StoreCapabilities.add.can} invocation`, { - cause: result.out.error, - }) - } - - // Return early if it was already uploaded. - if (result.out.ok.status === 'done') { - return link - } - - const responseAddUpload = result.out.ok - - const fetchWithUploadProgress = - options.fetchWithUploadProgress || - options.fetch || - globalThis.fetch.bind(globalThis) - - let fetchDidCallUploadProgressCb = false - const res = await retry( - async () => { - try { - const res = await fetchWithUploadProgress(responseAddUpload.url, { - method: 'PUT', - body: car, - headers: responseAddUpload.headers, - signal: options.signal, - onUploadProgress: (status) => { - fetchDidCallUploadProgressCb = true - if (options.onUploadProgress) - createUploadProgressHandler( - responseAddUpload.url, - options.onUploadProgress - )(status) - }, - // @ts-expect-error - this is needed by recent versions of node - see https://github.com/bluesky-social/atproto/pull/470 for more info - duplex: 'half', - }) - if (res.status >= 400 && res.status < 500) { - throw new AbortError(`upload failed: ${res.status}`) - } - return res - } catch (err) { - if (options.signal?.aborted === true) { - throw new AbortError('upload aborted') - } - throw err - } - }, - { - retries: options.retries ?? REQUEST_RETRIES, - } - ) - - if (!fetchDidCallUploadProgressCb && options.onUploadProgress) { - // the fetch implementation didn't support onUploadProgress - const carBlob = new Blob([car]) - options.onUploadProgress({ - total: carBlob.size, - loaded: carBlob.size, - lengthComputable: false, - }) - } - - if (!res.ok) { - throw new Error(`upload failed: ${res.status}`) - } - - return link -} - -/** - * Get details of a stored item. - * - * Required delegated capability proofs: `store/get` - * - * @param {import('./types.js').InvocationConfig} conf Configuration - * for the UCAN invocation. An object with `issuer`, `with` and `proofs`. - * - * The `issuer` is the signing authority that is issuing the UCAN - * invocation(s). It is typically the user _agent_. - * - * The `with` is the resource the invocation applies to. It is typically the - * DID of a space. - * - * The `proofs` are a set of capability delegations that prove the issuer - * has the capability to perform the action. - * - * The issuer needs the `store/get` delegated capability. - * @param {import('multiformats/link').Link} link CID of stored CAR file. - * @param {import('./types.js').RequestOptions} [options] - * @returns {Promise} - */ -export async function get( - { issuer, with: resource, proofs, audience }, - link, - options = {} -) { - /* c8 ignore next */ - const conn = options.connection ?? connection - const result = await retry( - async () => { - return await StoreCapabilities.get - .invoke({ - issuer, - /* c8 ignore next */ - audience: audience ?? servicePrincipal, - with: SpaceDID.from(resource), - nb: { link }, - proofs, - nonce: options.nonce, - }) - .execute(conn) - }, - { - onFailedAttempt: console.warn, - retries: options.retries ?? REQUEST_RETRIES, - } - ) - - if (!result.out.ok) { - throw new Error(`failed ${StoreCapabilities.get.can} invocation`, { - cause: result.out.error, - }) - } - - return result.out.ok -} - -/** - * List CAR files stored by the issuer. - * - * @param {import('./types.js').InvocationConfig} conf Configuration - * for the UCAN invocation. An object with `issuer`, `with` and `proofs`. - * - * The `issuer` is the signing authority that is issuing the UCAN - * invocation(s). It is typically the user _agent_. - * - * The `with` is the resource the invocation applies to. It is typically the - * DID of a space. - * - * The `proofs` are a set of capability delegations that prove the issuer - * has the capability to perform the action. - * - * The issuer needs the `store/list` delegated capability. - * @param {import('./types.js').ListRequestOptions} [options] - * @returns {Promise} - */ -export async function list( - { issuer, with: resource, proofs, audience }, - options = {} -) { - /* c8 ignore next */ - const conn = options.connection ?? connection - const result = await StoreCapabilities.list - .invoke({ - issuer, - /* c8 ignore next */ - audience: audience ?? servicePrincipal, - with: SpaceDID.from(resource), - proofs, - nb: { - cursor: options.cursor, - size: options.size, - pre: options.pre, - }, - nonce: options.nonce, - }) - .execute(conn) - - if (!result.out.ok) { - throw new Error(`failed ${StoreCapabilities.list.can} invocation`, { - cause: result.out.error, - }) - } - - return result.out.ok -} - -/** - * Remove a stored CAR file by CAR CID. - * - * @param {import('./types.js').InvocationConfig} conf Configuration - * for the UCAN invocation. An object with `issuer`, `with` and `proofs`. - * - * The `issuer` is the signing authority that is issuing the UCAN - * invocation(s). It is typically the user _agent_. - * - * The `with` is the resource the invocation applies to. It is typically the - * DID of a space. - * - * The `proofs` are a set of capability delegations that prove the issuer - * has the capability to perform the action. - * - * The issuer needs the `store/remove` delegated capability. - * @param {import('./types.js').CARLink} link CID of CAR file to remove. - * @param {import('./types.js').RequestOptions} [options] - */ -export async function remove( - { issuer, with: resource, proofs, audience }, - link, - options = {} -) { - /* c8 ignore next */ - const conn = options.connection ?? connection - const result = await StoreCapabilities.remove - .invoke({ - issuer, - /* c8 ignore next */ - audience: audience ?? servicePrincipal, - with: SpaceDID.from(resource), - nb: { link }, - proofs, - nonce: options.nonce, - }) - .execute(conn) - - if (!result.out.ok) { - throw new Error(`failed ${StoreCapabilities.remove.can} invocation`, { - cause: result.out.error, - }) - } - - return result.out -} diff --git a/packages/upload-client/src/types.ts b/packages/upload-client/src/types.ts index 8d95612d6..147dec25e 100644 --- a/packages/upload-client/src/types.ts +++ b/packages/upload-client/src/types.ts @@ -21,37 +21,25 @@ import { UCANConcludeSuccess, UCANConcludeFailure, BlobModel, - BlobAdd, - BlobAddSuccess, - BlobAddFailure, + SpaceBlobAdd, + SpaceBlobAddSuccess, + SpaceBlobAddFailure, BlobAllocateSuccess, BlobAllocateFailure, BlobAcceptSuccess, BlobAcceptFailure, - BlobRemove, - BlobRemoveSuccess, - BlobRemoveFailure, - BlobList, - BlobListSuccess, - BlobListFailure, - BlobGet, - BlobGetSuccess, - BlobGetFailure, - IndexAdd, - IndexAddSuccess, - IndexAddFailure, - StoreAdd, - StoreAddSuccess, - StoreAddSuccessUpload, - StoreAddSuccessDone, - StoreGet, - StoreGetFailure, - StoreList, - StoreListSuccess, - StoreListItem, - StoreRemove, - StoreRemoveSuccess, - StoreRemoveFailure, + SpaceBlobRemove, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure, + SpaceBlobList, + SpaceBlobListSuccess, + SpaceBlobListFailure, + SpaceBlobGet, + SpaceBlobGetSuccess, + SpaceBlobGetFailure, + SpaceIndexAdd, + SpaceIndexAddSuccess, + SpaceIndexAddFailure, UploadAdd, UploadAddSuccess, UploadList, @@ -62,7 +50,6 @@ import { ListResponse, CARLink, PieceLink, - StoreGetSuccess, UploadGet, UploadGetSuccess, UploadGetFailure, @@ -74,15 +61,15 @@ import { EgressRecordSuccess, EgressRecordFailure, ServiceAbility, -} from '@web3-storage/capabilities/types' -import { StorefrontService } from '@web3-storage/filecoin-client/storefront' +} from '@storacha/capabilities/types' +import { StorefrontService } from '@storacha/filecoin-client/storefront' import { code as pieceHashCode } from '@web3-storage/data-segment/multihash' import { ShardedDAGIndex, ShardDigest, SliceDigest, Position, -} from '@web3-storage/blob-index/types' +} from '@storacha/blob-index/types' type Override = Omit & R @@ -97,36 +84,24 @@ type FetchOptions = Override< export type { FetchOptions, BlobModel, - BlobAddSuccess, - BlobAddFailure, + SpaceBlobAddSuccess, + SpaceBlobAddFailure, BlobAllocateSuccess, BlobAllocateFailure, BlobAcceptSuccess, BlobAcceptFailure, - BlobRemove, - BlobRemoveSuccess, - BlobRemoveFailure, - BlobList, - BlobListSuccess, - BlobListFailure, - BlobGet, - BlobGetSuccess, - BlobGetFailure, - IndexAdd, - IndexAddSuccess, - IndexAddFailure, - StoreAdd, - StoreAddSuccess, - StoreAddSuccessUpload, - StoreAddSuccessDone, - StoreGetSuccess, - StoreGetFailure, - StoreList, - StoreListSuccess, - StoreListItem, - StoreRemove, - StoreRemoveSuccess, - StoreRemoveFailure, + SpaceBlobRemove, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure, + SpaceBlobList, + SpaceBlobListSuccess, + SpaceBlobListFailure, + SpaceBlobGet, + SpaceBlobGetSuccess, + SpaceBlobGetFailure, + SpaceIndexAdd, + SpaceIndexAddSuccess, + SpaceIndexAddFailure, UploadAdd, UploadAddSuccess, UploadGetSuccess, @@ -168,25 +143,35 @@ export interface Service extends StorefrontService { } space: { blob: { - add: ServiceMethod - remove: ServiceMethod - list: ServiceMethod + add: ServiceMethod + remove: ServiceMethod< + SpaceBlobRemove, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure + > + list: ServiceMethod< + SpaceBlobList, + SpaceBlobListSuccess, + SpaceBlobListFailure + > get: { 0: { - 1: ServiceMethod + 1: ServiceMethod< + SpaceBlobGet, + SpaceBlobGetSuccess, + SpaceBlobGetFailure + > } } } index: { - add: ServiceMethod + add: ServiceMethod< + SpaceIndexAdd, + SpaceIndexAddSuccess, + SpaceIndexAddFailure + > } } - store: { - add: ServiceMethod - get: ServiceMethod - remove: ServiceMethod - list: ServiceMethod - } upload: { add: ServiceMethod get: ServiceMethod diff --git a/packages/upload-client/src/upload/add.js b/packages/upload-client/src/upload/add.js index f526ba653..d2d71bada 100644 --- a/packages/upload-client/src/upload/add.js +++ b/packages/upload-client/src/upload/add.js @@ -1,5 +1,5 @@ -import * as UploadCapabilities from '@web3-storage/capabilities/upload' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as UploadCapabilities from '@storacha/capabilities/upload' +import { SpaceDID } from '@storacha/capabilities/utils' import retry from 'p-retry' import { servicePrincipal, connection } from '../service.js' import { REQUEST_RETRIES } from '../constants.js' diff --git a/packages/upload-client/src/upload/get.js b/packages/upload-client/src/upload/get.js index 42433f87e..f10de36f9 100644 --- a/packages/upload-client/src/upload/get.js +++ b/packages/upload-client/src/upload/get.js @@ -1,5 +1,5 @@ -import * as UploadCapabilities from '@web3-storage/capabilities/upload' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as UploadCapabilities from '@storacha/capabilities/upload' +import { SpaceDID } from '@storacha/capabilities/utils' import retry from 'p-retry' import { servicePrincipal, connection } from '../service.js' import { REQUEST_RETRIES } from '../constants.js' diff --git a/packages/upload-client/src/upload/list.js b/packages/upload-client/src/upload/list.js index 0075b416a..1921b4a92 100644 --- a/packages/upload-client/src/upload/list.js +++ b/packages/upload-client/src/upload/list.js @@ -1,5 +1,5 @@ -import * as UploadCapabilities from '@web3-storage/capabilities/upload' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as UploadCapabilities from '@storacha/capabilities/upload' +import { SpaceDID } from '@storacha/capabilities/utils' import { servicePrincipal, connection } from '../service.js' /** diff --git a/packages/upload-client/src/upload/remove.js b/packages/upload-client/src/upload/remove.js index 488edaa91..26ee8479a 100644 --- a/packages/upload-client/src/upload/remove.js +++ b/packages/upload-client/src/upload/remove.js @@ -1,5 +1,5 @@ -import * as UploadCapabilities from '@web3-storage/capabilities/upload' -import { SpaceDID } from '@web3-storage/capabilities/utils' +import * as UploadCapabilities from '@storacha/capabilities/upload' +import { SpaceDID } from '@storacha/capabilities/utils' import { servicePrincipal, connection } from '../service.js' /** diff --git a/packages/upload-client/test/blob.test.js b/packages/upload-client/test/blob.test.js index 327aa8a09..f56284e68 100644 --- a/packages/upload-client/test/blob.test.js +++ b/packages/upload-client/test/blob.test.js @@ -5,11 +5,11 @@ import * as Server from '@ucanto/server' import { provide } from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import * as Signer from '@ucanto/principal/ed25519' -import * as UCAN from '@web3-storage/capabilities/ucan' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' +import * as UCAN from '@storacha/capabilities/ucan' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' import * as Blob from '../src/blob/index.js' import { serviceSigner } from './fixtures.js' -import { randomBytes } from './helpers/random.js' +import { randomBlock, randomBytes } from './helpers/random.js' import { mockService } from './helpers/mocks.js' import { validateAuthorization, @@ -185,7 +185,7 @@ describe('Blob.add', () => { { connection } ), { - message: 'failed space/blob/add invocation', + message: 'failed ucan/conclude for http/put invocation', } ) }) @@ -499,7 +499,10 @@ describe('Blob.add', () => { ) }) - it('throws for bucket URL server error 5xx', async () => { + it('throws for bucket URL server error 5xx', async function () { + // allow time for retries + this.timeout(10_000) + const space = await Signer.generate() const agent = await Signer.generate() const bytes = await randomBytes(128) @@ -688,6 +691,7 @@ describe('Blob.list', () => { digest: bytesHash.bytes, size: 123, }, + cause: (await randomBlock(32)).cid, insertedAt: '1970-01-01T00:00:00.000Z', }, ], @@ -767,6 +771,7 @@ describe('Blob.list', () => { digest: bytesHash[0].bytes, size: 123, }, + cause: (await randomBlock(32)).cid, insertedAt: '1970-01-01T00:00:00.000Z', }, ], @@ -779,6 +784,7 @@ describe('Blob.list', () => { digest: bytesHash[1].bytes, size: 123, }, + cause: (await randomBlock(32)).cid, insertedAt: '1970-01-01T00:00:00.000Z', }, ], @@ -1037,6 +1043,7 @@ describe('Blob.get', () => { ok: { cause: invocation.link(), blob: { digest: bytesHash.bytes, size: bytes.length }, + insertedAt: '1970-01-01T00:00:00.000Z', }, } }), diff --git a/packages/upload-client/test/dag-index.test.js b/packages/upload-client/test/dag-index.test.js index 14e2cd07e..88dace38c 100644 --- a/packages/upload-client/test/dag-index.test.js +++ b/packages/upload-client/test/dag-index.test.js @@ -3,7 +3,7 @@ import * as Client from '@ucanto/client' import * as Server from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import * as Signer from '@ucanto/principal/ed25519' -import * as IndexCapabilities from '@web3-storage/capabilities/index' +import * as IndexCapabilities from '@storacha/capabilities/space/index' import * as Index from '../src/index/index.js' import { serviceSigner } from './fixtures.js' import { randomCAR } from './helpers/random.js' diff --git a/packages/upload-client/test/helpers/car.js b/packages/upload-client/test/helpers/car.js index b802cc889..56d2b3a9b 100644 --- a/packages/upload-client/test/helpers/car.js +++ b/packages/upload-client/test/helpers/car.js @@ -7,7 +7,6 @@ import { toBlock } from './block.js' */ export async function toCAR(bytes) { const block = await toBlock(bytes) - // @ts-expect-error old multiformats in @ipld/car const { writer, out } = CarWriter.create(block.cid) writer.put(block) writer.close() diff --git a/packages/upload-client/test/helpers/filecoin.js b/packages/upload-client/test/helpers/filecoin.js index c89a9f321..6e47e2007 100644 --- a/packages/upload-client/test/helpers/filecoin.js +++ b/packages/upload-client/test/helpers/filecoin.js @@ -1,4 +1,4 @@ -import * as StorefrontCapabilities from '@web3-storage/capabilities/filecoin/storefront' +import * as StorefrontCapabilities from '@storacha/capabilities/filecoin/storefront' import * as Server from '@ucanto/server' /** diff --git a/packages/upload-client/test/helpers/mocks.js b/packages/upload-client/test/helpers/mocks.js index e8530ccdd..1805eb168 100644 --- a/packages/upload-client/test/helpers/mocks.js +++ b/packages/upload-client/test/helpers/mocks.js @@ -11,10 +11,9 @@ const notImplemented = () => { * blob: Partial * index: Partial * }> - * store: Partial * upload: Partial * usage: Partial - * filecoin: Partial + * filecoin: Partial * }>} impl */ export function mockService(impl) { @@ -38,12 +37,6 @@ export function mockService(impl) { add: withCallCount(impl.space?.index?.add ?? notImplemented), }, }, - store: { - add: withCallCount(impl.store?.add ?? notImplemented), - get: withCallCount(impl.store?.get ?? notImplemented), - list: withCallCount(impl.store?.list ?? notImplemented), - remove: withCallCount(impl.store?.remove ?? notImplemented), - }, upload: { add: withCallCount(impl.upload?.add ?? notImplemented), get: withCallCount(impl.upload?.get ?? notImplemented), diff --git a/packages/upload-client/test/helpers/utils.js b/packages/upload-client/test/helpers/utils.js index 5ab28080b..252a93ea3 100644 --- a/packages/upload-client/test/helpers/utils.js +++ b/packages/upload-client/test/helpers/utils.js @@ -3,9 +3,9 @@ import * as Signer from '@ucanto/principal/ed25519' import { Receipt } from '@ucanto/core' import { Assert } from '@web3-storage/content-claims/capability' import * as Server from '@ucanto/server' -import * as HTTP from '@web3-storage/capabilities/http' -import * as W3sBlobCapabilities from '@web3-storage/capabilities/web3.storage/blob' -import { W3sBlob } from '@web3-storage/capabilities' +import * as HTTP from '@storacha/capabilities/http' +import * as BlobCapabilities from '@storacha/capabilities/blob' +import * as DID from '@ipld/dag-ucan/did' import { createConcludeInvocation } from '../../src/blob/add.js' import { randomCAR } from './random.js' @@ -24,7 +24,7 @@ Object.entries({ }).forEach(([name, url]) => { fetch(url).catch((error) => { console.warn( - `${name} is unreachable at ${url}. If tests are failing, try running \`pnpm --filter=@web3-storage/upload-client mock\`.` + `${name} is unreachable at ${url}. If tests are failing, try running \`pnpm --filter=@storacha/upload-client mock\`.` ) }) }) @@ -106,6 +106,8 @@ export const setupBlobAddWithHttpPutReceiptSuccessResponse = async function ( /** * @param {string} url + * @param {any} config + * @param {any} invocation * @param {boolean} hasHttpPutReceipt * @param {boolean} hasAcceptReceipt */ @@ -119,7 +121,7 @@ const setupBlobAddResponse = async function ( hasAcceptReceipt ) { const blob = invocation.capabilities[0].nb.blob - const blobAllocateTask = await W3sBlob.allocate + const blobAllocateTask = await BlobCapabilities.allocate .invoke({ issuer, audience, @@ -127,7 +129,7 @@ const setupBlobAddResponse = async function ( nb: { blob, cause: invocation.link(), - space: space.did(), + space: DID.parse(space.did()), }, expiration: Infinity, }) @@ -184,14 +186,14 @@ const setupBlobAddResponse = async function ( blobPutReceipt ).delegate() - const blobAcceptTask = await W3sBlobCapabilities.accept + const blobAcceptTask = await BlobCapabilities.accept .invoke({ issuer, audience, with: space.did(), nb: { blob, - space: space.did(), + space: DID.parse(space.did()), _put: { 'ucan/await': ['.out.ok', blobPutTask.link()] }, }, proofs, diff --git a/packages/upload-client/test/index.test.js b/packages/upload-client/test/index.test.js index 7dfb60abe..7172c13da 100644 --- a/packages/upload-client/test/index.test.js +++ b/packages/upload-client/test/index.test.js @@ -4,11 +4,11 @@ import * as Server from '@ucanto/server' import { provide } from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import * as Signer from '@ucanto/principal/ed25519' -import * as UCAN from '@web3-storage/capabilities/ucan' -import * as BlobCapabilities from '@web3-storage/capabilities/blob' -import * as IndexCapabilities from '@web3-storage/capabilities/index' -import * as UploadCapabilities from '@web3-storage/capabilities/upload' -import * as StorefrontCapabilities from '@web3-storage/capabilities/filecoin/storefront' +import * as UCAN from '@storacha/capabilities/ucan' +import * as BlobCapabilities from '@storacha/capabilities/space/blob' +import * as IndexCapabilities from '@storacha/capabilities/space/index' +import * as UploadCapabilities from '@storacha/capabilities/upload' +import * as StorefrontCapabilities from '@storacha/capabilities/filecoin/storefront' import { Piece } from '@web3-storage/data-segment' import { uploadFile, uploadDirectory, uploadCAR } from '../src/index.js' import { serviceSigner } from './fixtures.js' @@ -614,7 +614,7 @@ describe('uploadDirectory', () => { ]) function createSimpleMockUploadServer() { /** - * @type {Array>>} + * @type {Array>>} */ const invocations = [] const service = mockService({ @@ -1144,7 +1144,7 @@ describe('uploadCAR', () => { issuer: space, audience: agent, with: space.did(), - nb: /** @type {import('@web3-storage/capabilities/types').BlobAdd['nb']} */ ( + nb: /** @type {import('@storacha/capabilities/types').SpaceBlobAdd['nb']} */ ( nb ), expiration: Infinity, @@ -1156,7 +1156,7 @@ describe('uploadCAR', () => { issuer: space, audience: agent, with: space.did(), - nb: /** @type {import('@web3-storage/capabilities/types').IndexAdd['nb']} */ ( + nb: /** @type {import('@storacha/capabilities/types').SpaceIndexAdd['nb']} */ ( nb ), expiration: Infinity, @@ -1168,7 +1168,7 @@ describe('uploadCAR', () => { issuer: space, audience: agent, with: space.did(), - nb: /** @type {import('@web3-storage/capabilities/types').UploadAdd['nb']} */ ( + nb: /** @type {import('@storacha/capabilities/types').UploadAdd['nb']} */ ( nb ), expiration: Infinity, diff --git a/packages/upload-client/test/sharding.test.js b/packages/upload-client/test/sharding.test.js index 79a3ef2ab..6c1444c32 100644 --- a/packages/upload-client/test/sharding.test.js +++ b/packages/upload-client/test/sharding.test.js @@ -78,24 +78,22 @@ describe('ShardingStream', () => { await randomBlock(32), // encoded block length = 70 ] - /** @type {import('../src/types.js').CARFile[]} */ + /** @type {import('../src/types.js').IndexedCARFile[]} */ const shards = [] + let i = 0 await new ReadableStream({ pull(controller) { - const block = blocks.shift() + const block = blocks[i] if (!block) return controller.close() controller.enqueue(block) + i++ }, }) - // shard with no roots = encoded block (166) + CAR header (18) = 183 - // shard with no roots = encoded block (102) + CAR header (18) = 120 - // shard with 1 root = encoded block (70) + CAR header (18) = 88 - // shard with 1 root = encoded block (70) + CAR header (59) = 155 - // i.e. shard size of 208 (120 + 88) should allow us 1 shard with 0 roots - // and then 1 shard with 2 blocks that, when encoded as a CAR with 1 root - // will actually exceed the shard size. It must then be refactored into - // 2 shards. - .pipeThrough(new ShardingStream({ shardSize: 208 })) + // 166 + 102 + 70 + 18 (0 root CAR header) = 356 + // 166 + 102 + 70 + 59 (1 root CAR header) = 397 + // Choose 360 as shard size so when CAR header with a root is added, the + // 3rd block is moved into a new shard. + .pipeThrough(new ShardingStream({ shardSize: 360 })) .pipeTo( new WritableStream({ write: (s) => { @@ -104,7 +102,39 @@ describe('ShardingStream', () => { }) ) - assert.equal(shards.length, 3) + assert.equal(shards.length, 2) + + const shard0Bytes = new Uint8Array(await shards[0].arrayBuffer()) + const shard1Bytes = new Uint8Array(await shards[1].arrayBuffer()) + + // block 0 and 1 should be in shard 0 + const slice0 = shards[0].slices.get(blocks[0].cid.multihash) + assert.ok(slice0) + assert( + equals( + blocks[0].bytes, + shard0Bytes.slice(slice0[0], slice0[0] + slice0[1]) + ) + ) + + const slice1 = shards[0].slices.get(blocks[1].cid.multihash) + assert.ok(slice1) + assert( + equals( + blocks[1].bytes, + shard0Bytes.slice(slice1[0], slice1[0] + slice1[1]) + ) + ) + + // block 2 should be in shard 1 + const slice2 = shards[1].slices.get(blocks[2].cid.multihash) + assert.ok(slice2) + assert( + equals( + blocks[2].bytes, + shard1Bytes.slice(slice2[0], slice2[0] + slice2[1]) + ) + ) }) it('exceeds shard size when block is encoded with root CID', async () => { diff --git a/packages/upload-client/test/store.test.js b/packages/upload-client/test/store.test.js deleted file mode 100644 index 90574ef8b..000000000 --- a/packages/upload-client/test/store.test.js +++ /dev/null @@ -1,786 +0,0 @@ -import assert from 'assert' -import * as Client from '@ucanto/client' -import * as Server from '@ucanto/server' -import { provide } from '@ucanto/server' -import * as CAR from '@ucanto/transport/car' -import * as Signer from '@ucanto/principal/ed25519' -import * as StoreCapabilities from '@web3-storage/capabilities/store' -import * as Store from '../src/store.js' -import { serviceSigner } from './fixtures.js' -import { randomCAR } from './helpers/random.js' -import { mockService } from './helpers/mocks.js' -import { validateAuthorization } from './helpers/utils.js' -import { fetchWithUploadProgress } from '../src/fetch-with-upload-progress.js' - -describe('Store.add', () => { - it('stores a DAG with the service', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - /** @type {import('../src/types.js').StoreAddSuccessUpload} */ - const res = { - status: 'upload', - headers: { 'x-test': 'true' }, - url: 'http://localhost:9200', - link: car.cid, - with: space.did(), - allocated: car.size, - } - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, ({ invocation }) => { - assert.equal(invocation.issuer.did(), agent.did()) - assert.equal(invocation.capabilities.length, 1) - const invCap = invocation.capabilities[0] - assert.equal(invCap.can, StoreCapabilities.add.can) - assert.equal(invCap.with, space.did()) - assert.equal(String(invCap.nb?.link), car.cid.toString()) - return { ok: res } - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - /** @type {import('../src/types.js').ProgressStatus[]} */ - const progress = [] - const carCID = await Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { - connection, - onUploadProgress: (status) => { - assert(typeof status.loaded === 'number' && status.loaded > 0) - progress.push(status) - }, - fetchWithUploadProgress, - } - ) - - assert(service.store.add.called) - assert.equal(service.store.add.callCount, 1) - assert.equal( - progress.reduce((max, { loaded }) => Math.max(max, loaded), 0), - 225 - ) - - assert(carCID) - assert.equal(carCID.toString(), car.cid.toString()) - - // make sure it can also work without fetchWithUploadProgress - /** @type {import('../src/types.js').ProgressStatus[]} */ - let progressWithoutUploadProgress = [] - const addedWithoutUploadProgress = await Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { - connection, - onUploadProgress: (status) => { - progressWithoutUploadProgress.push(status) - }, - } - ) - assert.equal(addedWithoutUploadProgress.toString(), car.cid.toString()) - assert.equal( - progressWithoutUploadProgress.reduce( - (max, { loaded }) => Math.max(max, loaded), - 0 - ), - 225 - ) - }) - - it('throws for bucket URL client error 4xx', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - /** @type {import('../src/types.js').StoreAddSuccessUpload} */ - const res = { - status: 'upload', - headers: { 'x-test': 'true' }, - url: 'http://localhost:9400', // this bucket always returns a 400 - link: car.cid, - with: space.did(), - allocated: car.size, - } - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, () => ({ ok: res })), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { connection } - ), - { - message: 'upload failed: 400', - } - ) - }) - - it('throws for bucket URL server error 5xx', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - /** @type {import('../src/types.js').StoreAddSuccessUpload} */ - const res = { - status: 'upload', - headers: { 'x-test': 'true' }, - url: 'http://localhost:9500', // this bucket always returns a 500 - link: car.cid, - with: space.did(), - allocated: car.size, - } - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, () => ({ ok: res })), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { connection } - ), - { - message: 'upload failed: 500', - } - ) - }) - - it('skips sending CAR if status = done', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - /** @type {import('../src/types.js').StoreAddSuccessDone} */ - const res = { - status: 'done', - // @ts-expect-error - headers: { 'x-test': 'true' }, - } - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, () => ({ ok: res })), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const carCID = await Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { - connection, - } - ) - - assert(service.store.add.called) - assert.equal(service.store.add.callCount, 1) - - assert(carCID) - assert.equal(carCID.toString(), car.cid.toString()) - }) - - it('aborts', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - /** @type {import('../src/types.js').StoreAddSuccess} */ - const res = { - status: 'upload', - headers: { 'x-test': 'true' }, - url: 'http://localhost:9200', - link: car.cid, - with: space.did(), - allocated: car.size, - } - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, () => ({ ok: res })), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const controller = new AbortController() - controller.abort() // already aborted - - await assert.rejects( - Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { - connection, - signal: controller.signal, - } - ), - { name: 'Error', message: 'upload aborted' } - ) - }) - - it('throws on service error', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.add.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - add: provide(StoreCapabilities.add, () => { - throw new Server.Failure('boom') - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.add( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car, - { connection } - ), - { message: 'failed store/add invocation' } - ) - }) -}) - -describe('Store.list', () => { - it('lists stored CAR files', async () => { - const car = await randomCAR(128) - const res = { - cursor: 'test', - size: 1000, - results: [ - { - link: car.cid, - size: 123, - insertedAt: '1970-01-01T00:00:00.000Z', - }, - ], - } - - const space = await Signer.generate() - const agent = await Signer.generate() - - const proofs = [ - await StoreCapabilities.list.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - list: provide(StoreCapabilities.list, ({ invocation }) => { - assert.equal(invocation.issuer.did(), agent.did()) - assert.equal(invocation.capabilities.length, 1) - const invCap = invocation.capabilities[0] - assert.equal(invCap.can, StoreCapabilities.list.can) - assert.equal(invCap.with, space.did()) - return { ok: res } - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const list = await Store.list( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - { connection } - ) - - assert(service.store.list.called) - assert.equal(service.store.list.callCount, 1) - - assert.equal(list.cursor, res.cursor) - assert.equal(list.size, res.size) - assert(list.results) - assert.equal(list.results.length, res.results.length) - list.results.forEach((r, i) => { - assert.deepEqual(r.link, res.results[i].link) - assert.deepEqual(r.size, res.results[i].size) - }) - }) - - it('paginates', async () => { - const cursor = 'test' - const page0 = { - cursor, - size: 1, - results: [ - { - link: (await randomCAR(128)).cid, - size: 123, - insertedAt: '1970-01-01T00:00:00.000Z', - }, - ], - } - const page1 = { - size: 1, - results: [ - { - link: (await randomCAR(128)).cid, - size: 123, - insertedAt: '1970-01-01T00:00:00.000Z', - }, - ], - } - - const space = await Signer.generate() - const agent = await Signer.generate() - - const proofs = [ - await StoreCapabilities.list.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - list: provide(StoreCapabilities.list, ({ invocation }) => { - assert.equal(invocation.issuer.did(), agent.did()) - assert.equal(invocation.capabilities.length, 1) - const invCap = invocation.capabilities[0] - assert.equal(invCap.can, StoreCapabilities.list.can) - assert.equal(invCap.with, space.did()) - assert.equal(invCap.nb?.size, 1) - return { ok: invCap.nb?.cursor === cursor ? page1 : page0 } - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const results0 = await Store.list( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - { size: 1, connection } - ) - const results1 = await Store.list( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - { size: 1, cursor: results0.cursor, connection } - ) - - assert(service.store.list.called) - assert.equal(service.store.list.callCount, 2) - - assert.equal(results0.cursor, cursor) - assert(results0.results) - assert.equal(results0.results.length, page0.results.length) - results0.results.forEach((r, i) => { - assert.equal(r.link.toString(), page0.results[i].link.toString()) - assert.equal(r.size, page0.results[i].size) - }) - - assert(results1.results) - assert.equal(results1.cursor, undefined) - assert.equal(results1.results.length, page1.results.length) - results1.results.forEach((r, i) => { - assert.equal(r.link.toString(), page1.results[i].link.toString()) - assert.equal(r.size, page1.results[i].size) - }) - }) - - it('throws on service error', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - - const proofs = [ - await StoreCapabilities.list.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - list: provide(StoreCapabilities.list, () => { - throw new Server.Failure('boom') - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.list( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - { connection } - ), - { - message: 'failed store/list invocation', - } - ) - }) -}) - -describe('Store.remove', () => { - it('removes a stored CAR file', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.remove.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - remove: provide(StoreCapabilities.remove, ({ invocation }) => { - assert.equal(invocation.issuer.did(), agent.did()) - assert.equal(invocation.capabilities.length, 1) - const invCap = invocation.capabilities[0] - assert.equal(invCap.can, StoreCapabilities.remove.can) - assert.equal(invCap.with, space.did()) - assert.equal(String(invCap.nb?.link), car.cid.toString()) - return { ok: { size: car.size } } - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const result = await Store.remove( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car.cid, - { connection } - ) - - assert(service.store.remove.called) - assert.equal(service.store.remove.callCount, 1) - - assert(result.ok) - assert.equal(result.ok.size, car.size) - }) - - it('throws on service error', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.remove.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - remove: provide(StoreCapabilities.remove, () => { - throw new Server.Failure('boom') - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.remove( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car.cid, - { connection } - ), - { message: 'failed store/remove invocation' } - ) - }) -}) - -describe('Store.get', () => { - it('gets stored item', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.get.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - get: provide(StoreCapabilities.get, ({ invocation, capability }) => { - assert.equal(invocation.issuer.did(), agent.did()) - assert.equal(invocation.capabilities.length, 1) - assert.equal(capability.can, StoreCapabilities.get.can) - assert.equal(capability.with, space.did()) - assert.equal(String(capability.nb?.link), car.cid.toString()) - return { - ok: { - link: car.cid, - size: car.size, - insertedAt: new Date().toISOString(), - }, - } - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - const result = await Store.get( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car.cid, - { connection } - ) - - assert(service.store.get.called) - assert.equal(service.store.get.callCount, 1) - - assert.equal(result.link.toString(), car.cid.toString()) - assert.equal(result.size, car.size) - }) - - it('throws on service error', async () => { - const space = await Signer.generate() - const agent = await Signer.generate() - const car = await randomCAR(128) - - const proofs = [ - await StoreCapabilities.get.delegate({ - issuer: space, - audience: agent, - with: space.did(), - expiration: Infinity, - }), - ] - - const service = mockService({ - store: { - get: provide(StoreCapabilities.get, () => { - throw new Server.Failure('boom') - }), - }, - }) - - const server = Server.create({ - id: serviceSigner, - service, - codec: CAR.inbound, - validateAuthorization, - }) - const connection = Client.connect({ - id: serviceSigner, - codec: CAR.outbound, - channel: server, - }) - - await assert.rejects( - Store.get( - { issuer: agent, with: space.did(), proofs, audience: serviceSigner }, - car.cid, - { connection } - ), - { message: 'failed store/get invocation' } - ) - }) -}) diff --git a/packages/upload-client/test/upload.test.js b/packages/upload-client/test/upload.test.js index 7cd5a4b0e..8584261b1 100644 --- a/packages/upload-client/test/upload.test.js +++ b/packages/upload-client/test/upload.test.js @@ -4,7 +4,7 @@ import * as Server from '@ucanto/server' import { provide } from '@ucanto/server' import * as CAR from '@ucanto/transport/car' import * as Signer from '@ucanto/principal/ed25519' -import * as UploadCapabilities from '@web3-storage/capabilities/upload' +import * as UploadCapabilities from '@storacha/capabilities/upload' import * as Upload from '../src/upload/index.js' import { serviceSigner } from './fixtures.js' import { randomCAR } from './helpers/random.js' diff --git a/packages/w3up-client/CHANGELOG.md b/packages/w3up-client/CHANGELOG.md index fbf6b441f..cc01577cf 100644 --- a/packages/w3up-client/CHANGELOG.md +++ b/packages/w3up-client/CHANGELOG.md @@ -1,5 +1,121 @@ # Changelog +## [1.1.4](https://github.com/storacha/upload-service/compare/client-v1.1.3...client-v1.1.4) (2025-01-22) + + +### Other Changes + +* upgrade dependencies ([#124](https://github.com/storacha/upload-service/issues/124)) ([e743572](https://github.com/storacha/upload-service/commit/e743572e4a7caad5076472fe0b6e8bfeac7c44db)) + +## [1.1.3](https://github.com/storacha/upload-service/compare/client-v1.1.2...client-v1.1.3) (2025-01-20) + + +### Other Changes + +* sync with w3up repo ([#119](https://github.com/storacha/upload-service/issues/119)) ([d86e52c](https://github.com/storacha/upload-service/commit/d86e52cfdb58c38a8499aaed03260f683eceae44)) + +## [1.1.2](https://github.com/storacha/upload-service/compare/client-v1.1.1...client-v1.1.2) (2024-12-20) + + +### Fixes + +* **w3up-client:** authorize agent to use space ([#115](https://github.com/storacha/upload-service/issues/115)) ([3719670](https://github.com/storacha/upload-service/commit/3719670d3b963221c1d02f15ae5f92a32ca07a52)) + +## [1.1.1](https://github.com/storacha/upload-service/compare/client-v1.1.0...client-v1.1.1) (2024-12-19) + + +### Fixes + +* **w3up-client:** create space options ([#113](https://github.com/storacha/upload-service/issues/113)) ([5eec331](https://github.com/storacha/upload-service/commit/5eec331370f7399443835298d96d2411395edd03)) + +## [1.1.0](https://github.com/storacha/upload-service/compare/client-v1.0.6...client-v1.1.0) (2024-12-19) + + +### Features + +* content serve authorization ([#1590](https://github.com/storacha/upload-service/issues/1590)) + set default gateway ([#99](https://github.com/storacha/upload-service/issues/99)) ([6cbb202](https://github.com/storacha/upload-service/commit/6cbb2027c829189937363b374e258bb1a2b07722)) + + +### Other Changes + +* **capabilities:** top level filecoin cap ([#105](https://github.com/storacha/upload-service/issues/105)) ([671a411](https://github.com/storacha/upload-service/commit/671a411c94f18eb6498a1751eebed7b4d4ea0c35)) +* **main:** release client 1.0.6 ([27cb383](https://github.com/storacha/upload-service/commit/27cb383ea5aae32ca44cc2986f781458130fbffb)) +* **main:** release client 1.0.6 ([#104](https://github.com/storacha/upload-service/issues/104)) ([07f27a2](https://github.com/storacha/upload-service/commit/07f27a22a942bde67b55e785b2e3785906d63422)) +* **main:** release upload-api 1.1.8 ([#103](https://github.com/storacha/upload-service/issues/103)) ([e71494a](https://github.com/storacha/upload-service/commit/e71494a12fbd6a93bf2871eec1b101d4b02af38f)) + +## [1.0.6](https://github.com/storacha/upload-service/compare/client-v1.0.5...client-v1.0.6) (2024-12-12) + + +### Fixes + +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([98ab50c](https://github.com/storacha/upload-service/commit/98ab50cf0a5c7985a567e9507b04d948e425d623)) +* **egress/record:** rename capability ([#1572](https://github.com/storacha/upload-service/issues/1572)) ([#97](https://github.com/storacha/upload-service/issues/97)) ([df8b9a2](https://github.com/storacha/upload-service/commit/df8b9a2dd88871d33bd836aea431d7dbc2bc590c)) + +## [1.0.5](https://github.com/storacha/upload-service/compare/client-v1.0.4...client-v1.0.5) (2024-12-02) + + +### Other Changes + +* Trigger release ([05444ef](https://github.com/storacha/upload-service/commit/05444ef59909bd8f5382d4df289b08812e08a9c0)) +* Trigger release ([#94](https://github.com/storacha/upload-service/issues/94)) ([36be4bf](https://github.com/storacha/upload-service/commit/36be4bfbf38f49f9388d77c3cde37f6c7e5961be)) + +## [1.0.4](https://github.com/storacha/upload-service/compare/client-v1.0.3...client-v1.0.4) (2024-12-02) + + +### Other Changes + +* **main:** release client 1.0.3 ([17ff92b](https://github.com/storacha/upload-service/commit/17ff92b1ea44ae0e2fce2fa97b40ad578989a9e2)) +* **main:** release client 1.0.3 ([#85](https://github.com/storacha/upload-service/issues/85)) ([0ea3a80](https://github.com/storacha/upload-service/commit/0ea3a80517eb1f7d8dd0d3e2eb8cc4f72c4a93ba)) +* Revert "chore(main): release client 1.0.3" ([#84](https://github.com/storacha/upload-service/issues/84)) ([2f354c4](https://github.com/storacha/upload-service/commit/2f354c423d60d929fc24bb902d262b3ae7b89ee0)) + +## [1.0.3](https://github.com/storacha/upload-service/compare/client-v1.0.2...client-v1.0.3) (2024-11-29) + + +### Fixes + +* compatibility with legacy w3up client ([#59](https://github.com/storacha/upload-service/issues/59)) ([7185046](https://github.com/storacha/upload-service/commit/7185046e3186bef9b4f56f9e6c1c94a0c576fc53)) + + +### Other Changes + +* **main:** release client 1.0.3 ([b0ccad7](https://github.com/storacha/upload-service/commit/b0ccad779875b9f64143f901e0f218faad186a83)) +* **main:** release client 1.0.3 ([#79](https://github.com/storacha/upload-service/issues/79)) ([7c336f2](https://github.com/storacha/upload-service/commit/7c336f2861fecd1afddbf026896e2c4fbd45f0ee)) +* Revert "chore(main): release client 1.0.3" ([#84](https://github.com/storacha/upload-service/issues/84)) ([2f354c4](https://github.com/storacha/upload-service/commit/2f354c423d60d929fc24bb902d262b3ae7b89ee0)) + +## [1.0.2](https://github.com/storacha/upload-service/compare/client-v1.0.1...client-v1.0.2) (2024-11-27) + + +### Fixes + +* Fix type references ([cc09933](https://github.com/storacha/upload-service/commit/cc09933ea0132e10f39f27304a273c443d3da3fa)) +* Fix type references ([#57](https://github.com/storacha/upload-service/issues/57)) ([10e6c7d](https://github.com/storacha/upload-service/commit/10e6c7d95becbe1f804a5195b5255cf95394351b)) + +## [1.0.1](https://github.com/storacha/upload-service/compare/client-v1.0.0...client-v1.0.1) (2024-11-12) + + +### Fixes + +* use configured receipts endpoint ([2e452c0](https://github.com/storacha/upload-service/commit/2e452c0c75e1ba34a6c5cb4cb3cd3a7c9f1c01ba)) + + +### Other Changes + +* format ([f740119](https://github.com/storacha/upload-service/commit/f74011982962d0c4e0b70b235d146cd611b8ea77)) + +## 1.0.0 (2024-11-05) + + +### Features + +* remove store protocol ([d59ec88](https://github.com/storacha/upload-service/commit/d59ec883ace9c3f084772f9520b6df81cc13b7af)) +* remove store protocol ([#13](https://github.com/storacha/upload-service/issues/13)) ([0028049](https://github.com/storacha/upload-service/commit/0028049f0bd3fcb816968687694c4611a5147148)) + + +### Other Changes + +* attw ([cad14ad](https://github.com/storacha/upload-service/commit/cad14add236349a72696478b0defb2e4ae163a4d)) +* formatter ([f4f5f5a](https://github.com/storacha/upload-service/commit/f4f5f5accc0c80f3dfb1b6916d04df0e594c89af)) + ## [16.4.0](https://github.com/storacha/w3up/compare/w3up-client-v16.3.0...w3up-client-v16.4.0) (2024-10-24) diff --git a/packages/w3up-client/DELETEME b/packages/w3up-client/DELETEME new file mode 100644 index 000000000..5479a2ff9 --- /dev/null +++ b/packages/w3up-client/DELETEME @@ -0,0 +1 @@ +This file was added to trigger a releease. Delete at next opportunity. \ No newline at end of file diff --git a/packages/w3up-client/README.md b/packages/w3up-client/README.md index 87ce444be..829f5fe9a 100644 --- a/packages/w3up-client/README.md +++ b/packages/w3up-client/README.md @@ -1,19 +1,19 @@ -

-

The main JavaScript client for the w3up platform by https://web3.storage

+

+

The main JavaScript client for the Storacha Network

- GitHub Workflow Status - - X Follow - License: Apache-2.0 OR MIT + GitHub Workflow Status + + X Follow + License: Apache-2.0 OR MIT

## About -`@web3-storage/w3up-client` is a JavaScript library that provides a convenient interface to the w3up platform, a simple "on-ramp" to the content-addressed decentralized IPFS network. +`@storacha/client` is a JavaScript library that provides a convenient interface to the w3up platform, a simple "on-ramp" to the content-addressed decentralized IPFS network. -This library is the user-facing "porcelain" client for interacting with w3up services from JavaScript. It wraps the lower-level [`@web3-storage/access`][access-client-github] and [`@web3-storage/upload-client`][upload-client-github] client packages, which target individual w3up services. We recommend using `w3up-client` instead of using those "plumbing" packages directly, but you may find them useful if you need more context on w3up's architecture and internals. +This library is the user-facing "porcelain" client for interacting with w3up services from JavaScript. It wraps the lower-level [`@storacha/access`][access-client-github] and [`@storacha/upload-client`][upload-client-github] client packages, which target individual w3up services. We recommend using `@storacha/client` instead of using those "plumbing" packages directly, but you may find them useful if you need more context on w3up's architecture and internals. -**`w3up-client` requires Node 18 or higher**. +**`w3up-client` requires modern browser or Node 18+**. > ⚠️❗ __Public Data__ 🌎: All data uploaded to w3up is available to anyone who requests it using the correct CID. Do not store any private or sensitive information in an unencrypted form using w3up. @@ -24,7 +24,7 @@ This library is the user-facing "porcelain" client for interacting with w3up ser - [How w3up and w3up-client use UCANs](#how-w3up-and-w3up-client-use-ucans) - [Space](#space) - [Agent](#agent) - - [Basic usage with web3.storage](#basic-usage-with-web3-storage) + - [Basic usage with storacha.network](#basic-usage-with-web3-storage) - [Creating a client object](#creating-a-client-object) - [Creating and registering Spaces](#creating-and-registering-spaces) - [Delegating from Space to Agent](#delegating-from-space-to-agent) @@ -41,19 +41,19 @@ This library is the user-facing "porcelain" client for interacting with w3up ser ## Install -You can add the `@web3-storage/w3up-client` package to your JavaScript or TypeScript project with `npm`: +You can add the `@storacha/client` package to your JavaScript or TypeScript project with `npm`: ```sh -npm install @web3-storage/w3up-client +npm install @storacha/client ``` ## Usage [API Reference](#api) -Most users' usage of `w3up-client` will be for interacting with web3.storage, a hosted storage product that developed w3up for their upload APIs. However, any user that has an implementation of w3up ([specs](https://github.com/storacha/specs), [protocol](https://github.com/storacha/w3up)) can configure `w3up-client` for their usage. +Most users' usage of `w3up-client` will be for interacting with storacha.network, a hosted storage product that developed w3up for their upload APIs. However, any user that has an implementation of w3up ([specs](https://github.com/storacha/specs), [protocol](https://github.com/storacha/upload-service)) can configure `w3up-client` for their usage. -For authorization, w3up services use [ucanto][ucanto], a Remote Procedure Call (RPC) framework built around [UCAN](https://ucan.xzy), or User Controlled Authorization Networks. UCANs are a powerful capability-based authorization system that allows fine-grained sharing of permissions through a process called _delegation_ on top of [public key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography). See our [intro to UCAN blog post](https://blog.web3.storage/posts/intro-to-ucan) for an overview of UCAN. +For authorization, w3up services use [ucanto][ucanto], a Remote Procedure Call (RPC) framework built around [UCAN](https://ucan.xzy), or User Controlled Authorization Networks. UCANs are a powerful capability-based authorization system that allows fine-grained sharing of permissions through a process called _delegation_ on top of [public key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography). See our [intro to UCAN blog post](https://blog.storacha.network/posts/intro-to-ucan) for an overview of UCAN. You can think about UCAN replacing bearer tokens in traditional APIs for authorization with w3up. Since any actor can be represented by a cryptographic keypair and permissions can be delegated to them, users can interact with w3up directly in cases where a developer might have needed to previously run additional back-end infrastructure to keep API keys secure. This can be extended even to have end users using applications integrated with w3up using their own keypair-based identity. @@ -65,11 +65,11 @@ UCAN-based APIs are centered around _capabilities_, which are comprised of an _a #### Space -When you upload data to w3up, your uploads are linked to a unique _Space_ that acts as a "namespace" for the data you upload. Each Space corresponds to a _DID_, or [Decentralized Identity Document](https://www.w3.org/TR/did-core/). In web3.storage's implementation of w3up, these Space DIDs generally use the key DID method, of the form `did:key:publicKey` with a corresponding private signing key. +When you upload data to w3up, your uploads are linked to a unique _Space_ that acts as a "namespace" for the data you upload. Each Space corresponds to a _DID_, or [Decentralized Identity Document](https://www.w3.org/TR/did-core/). In storacha.network's implementation of w3up, these Space DIDs generally use the key DID method, of the form `did:key:publicKey` with a corresponding private signing key. -When creating a Space using `w3up-client`, it generates this private key and `did:key` for you locally. To use web3.storage, you then register a Space by associating it with your email address. From there, when invoking storage capabilities with web3.storage, the Space `did:key` is the "resource" portion of the capability, while the ability is an action like `blob/add` or `blob/remove`. (A Space registered with web3.storage is imperfectly analogous to an "account" with web3.storage.) +When creating a Space using `w3up-client`, it generates this private key and `did:key` for you locally. To use storacha.network, you then register a Space by associating it with your email address. From there, when invoking storage capabilities with storacha.network, the Space `did:key` is the "resource" portion of the capability, while the ability is an action like `blob/add` or `blob/remove`. (A Space registered with storacha.network is imperfectly analogous to an "account" with storacha.network.) -Under the hood in the email registration process, your Space delegates the capabilities needed to use w3up to your email address, and this delegation is stored by web3.storage. If you need access to your Space in the future from any device, web3.storage allows you to reclaim those capabilities the same way you would reset a password in other services - using an email verification process. This means you don't need to store or manage Space private keys to use w3up - just create a new space, register it with w3up and use it from as many devices as you like. More on this "sign in" process is detailed in the next section on Agents. +Under the hood in the email registration process, your Space delegates the capabilities needed to use w3up to your email address, and this delegation is stored by storacha.network. If you need access to your Space in the future from any device, storacha.network allows you to reclaim those capabilities the same way you would reset a password in other services - using an email verification process. This means you don't need to store or manage Space private keys to use w3up - just create a new space, register it with w3up and use it from as many devices as you like. More on this "sign in" process is detailed in the next section on Agents. #### Agent @@ -79,36 +79,36 @@ The first time `w3up-client` is instantiated on a device, it creates an Agent au The delegation from a Space to your Agent that `w3up-client` needs can be passed either by verifying the email address the Space is registered to and claiming the UCAN delegation (`login(email)` then `capability.access.claim`) or directly if you have the UCAN delegation available locally (`addSpace(delegation)`). -### Basic usage with web3.storage +### Basic usage with storacha.network ```mermaid flowchart TD A[w3up-client instance] -->|Automatic if specific Agent is not passed when client object created|B(Create local Agent DID and key) - B --> |If Space has not yet been created|S(Create local Space, login client with your email address, and register Space + email address with web3.storage) + B --> |If Space has not yet been created|S(Create local Space, login client with your email address, and register Space + email address with storacha.network) S --> C(Get UCAN delegation from Space to Agent) C --> D(Upload to Space using Agent) ``` -All uses of `w3up-client` to upload with web3.storage follow the flow above. This section shows the most basic way to use the client to start storing data. For more complex integration options, check out the [integration options][https://github.com/storacha/w3up/blob/main/packages/w3up-client/README.md#integration-options] docs. For reference, check out the [API reference docs][docs] or the source code of the [`w3cli` package][w3cli-github], which uses `w3up-client` throughout. +All uses of `w3up-client` to upload with storacha.network follow the flow above. This section shows the most basic way to use the client to start storing data. For more complex integration options, check out the [integration options][https://github.com/storacha/upload-service/blob/main/packages/w3up-client/README.md#integration-options] docs. For reference, check out the [API reference docs][docs] or the source code of the [`w3cli` package][w3cli-github], which uses `w3up-client` throughout. -> By you or your users registering a w3up Space via email confirmation with [web3.storage](http://web3.storage), you agree to the [Terms of Service](https://web3.storage/docs/terms/). +> By you or your users registering a w3up Space via email confirmation with [storacha.network](http://storacha.network), you agree to the [Terms of Service](https://docs.storacha.network/terms/). #### Creating a client object The package provides a [static `create` function][docs-create] that returns a [`Client` object][docs-Client]. ```js -import { create } from '@web3-storage/w3up-client' +import { create } from '@storacha/client' const client = await create() ``` -By default, clients will create a new [`Agent`][access-docs-Agent] and put it in a persistent local [`Store`](https://github.com/storacha/w3up/tree/main/packages/access-client) if it can't find an existing one to load (so the next time the client is initialized on the same device, it will use the same `Agent`). +By default, clients will create a new [`Agent`][access-docs-Agent] and put it in a persistent local [`Store`](https://github.com/storacha/upload-service/tree/main/packages/access-client) if it can't find an existing one to load (so the next time the client is initialized on the same device, it will use the same `Agent`). -`create` accepts an optional [`ClientFactoryOptions` object][docs-ClientFactoryOptions] that can be used configured to use a non-default persistent `Store`. See the [`@web3-storage/access` docs](https://github.com/storacha/w3up/tree/main/packages/access-client) for more about `Store` configuration. If you'd like to bring your own Agent, you can initialize the client with your own storage [Driver](https://github.com/storacha/w3up/blob/main/packages/w3up-client/README.md#driver). An example would be using `Signer` from the [ucanto][ucanto] package. +`create` accepts an optional [`ClientFactoryOptions` object][docs-ClientFactoryOptions] that can be used configured to use a non-default persistent `Store`. See the [`@storacha/access` docs](https://github.com/storacha/upload-service/tree/main/packages/access-client) for more about `Store` configuration. If you'd like to bring your own Agent, you can initialize the client with your own storage [Driver](https://github.com/storacha/upload-service/blob/main/packages/w3up-client/README.md#driver). An example would be using `Signer` from the [ucanto][ucanto] package. ```js -import { create } from '@web3-storage/w3up-client' +import { create } from '@storacha/client' import * as Signer from '@ucanto/principal/ed25519' // Agents on Node should use Ed25519 keys const principal = Signer.parse(agentPrivateKey) // created by `npx ucan-key ed --json` in command line @@ -117,6 +117,20 @@ const client = await create({ principal }) Once initialized, you can access the client's `Agent` with the [`agent` getter][docs-Client#agent]. +##### Pre-built bundle +You can also import a pre-built bundle, which adds the exports from the client to a _global_ variable `StorachaClient`: +```html + + + +``` + #### Creating and registering Spaces A [`Space`][docs-Space] acts as a namespace for your uploads, and what your Agent will need a delegation from to store data with w3up. The first thing to do is login your Agent with your email address. Calling `login` will cause an email to be sent to the given address. Once a user clicks the confirmation link in the email, the `login` method will resolve. Make sure to check for errors, as `login` will fail if the email is not confirmed within the expiration timeout. Authorization needs to happen only once per agent. @@ -163,10 +177,10 @@ await client.setCurrentSpace(space.did()) # select the relevant Space DID that i ```mermaid sequenceDiagram - Client->>web3.storage w3up service: Here is my email address and Agent DID - web3.storage w3up service-->>Client: Please click the link to validate - Client-->>web3.storage w3up service: Email address validated - web3.storage w3up service->>Client: Here is a UCAN delegating permission from Space DID to Agent DID + Client->>storacha.network w3up service: Here is my email address and Agent DID + storacha.network w3up service-->>Client: Please click the link to validate + Client-->>storacha.network w3up service: Email address validated + storacha.network w3up service->>Client: Here is a UCAN delegating permission from Space DID to Agent DID ``` ##### Bringing your own Agent and delegation @@ -177,8 +191,8 @@ For uses of `w3up-client` in environments where the Agent is not persisted and/o import * as Signer from '@ucanto/principal/ed25519' // Agents on Node should use Ed25519 keys import { importDAG } from '@ucanto/core/delegation' import { CarReader } from '@ipld/car' -import * as Client from '@web3-storage/w3up-client' -import { StoreMemory } from '@web3-storage/w3up-client/stores/memory' +import * as Client from '@storacha/client' +import { StoreMemory } from '@storacha/client/stores/memory' async function main () { // from "bring your own Agent" example in `Creating a client object" section` @@ -257,7 +271,7 @@ sequenceDiagram participant User w3up-client in backend->>w3up-client in backend: Client set with Agent with delegation from Space User->>w3up-client in backend: Upload data - w3up-client in backend->>web3.storage w3up service: Upload data + w3up-client in backend->>storacha.network w3up service: Upload data ``` - For your backend to be scalable, you might consider using serverless workers or a queue in front of a server - In either case, you'll need a registered Space, and your client instance in your backend to have an Agent with a delegation from this Space @@ -270,12 +284,12 @@ sequenceDiagram sequenceDiagram participant w3up-client in user participant w3up-client in backend - participant web3.storage w3up service + participant storacha.network w3up service w3up-client in backend->>w3up-client in backend: Client created with Agent and delegation from Space w3up-client in user->>w3up-client in user: Client instantiated with default Agent w3up-client in user->>w3up-client in backend: Request delegation with user's Agent DID w3up-client in backend->>w3up-client in user: Send delegation from Space to user's Agent DID - w3up-client in user->>web3.storage w3up service: Upload data + w3up-client in user->>storacha.network w3up service: Upload data ``` - You will likely have `w3up-client` running in your end-user's client code, as well as backend code that's able to generate UCANs that delegate the ability to upload and pass them to your users (e.g., `w3up-client` running in a serverless worker) - For your backend to be scalable, you might consider using serverless workers or a queue in front of a server @@ -298,7 +312,7 @@ import * as DID from '@ipld/dag-ucan/did'; import * as Delegation from '@ucanto/core/delegation'; import { importDAG } from '@ucanto/core/delegation'; import * as Signer from '@ucanto/principal/ed25519'; -import * as Client from '@web3-storage/w3up-client'; +import * as Client from '@storacha/client'; async function backend(did: string) { // Load client with specific private key @@ -361,17 +375,17 @@ async function frontend() { sequenceDiagram participant User participant Application backend - participant web3.storage w3up service + participant storacha.network w3up service Application backend->>User: Front end code that includes w3up-client - User->>web3.storage w3up service: (If needed) Create Space and register it - User->>web3.storage w3up service: (If needed) Use Agent email verification to "log in" to Space - User->>web3.storage w3up service: Upload data using w3up-client + User->>storacha.network w3up service: (If needed) Create Space and register it + User->>storacha.network w3up service: (If needed) Use Agent email verification to "log in" to Space + User->>storacha.network w3up service: Upload data using w3up-client ``` - If you want your user to own their own Space, you'll likely be relying on the `w3up-client` methods to create a Space, authorize the Space, and authorize the Agent on the end user-side; from there they can run any of the `upload` methods - - Doing this does take some of the UX out of your control; for instance, when web3.storage fully launches with w3up, your users will have to set up their payment methods with web3.storage + - Doing this does take some of the UX out of your control; for instance, when storacha.network fully launches with w3up, your users will have to set up their payment methods with storacha.network - Note that this alone does not give visibility into which of your end users are uploading what; to track this, you'll probably need them to send you that information separately (e.g., once they've run `upload` and get back a content CID, you can have them send that CID to you for tracking) - There is a world of possibilities with your users "bringing their own identity" for their Space; you could explore how crypto wallet private keys, Apple Passkey, and more might map to Space DIDs and have the client use those -- If you have code snippet(s) that works for you, please share them in a PR or [Github issue](https://github.com/storacha/w3up/issues) and we'll link them here! +- If you have code snippet(s) that works for you, please share them in a PR or [Github issue](https://github.com/storacha/upload-service/issues) and we'll link them here! ### Environments requiring wasm import @@ -827,7 +841,7 @@ The `with` field contains a resource URI, often a `did:key` URI that identifies The optional `nb` (_nota bene_) field contains "caveats" that add supplemental information to a UCAN invocation or delegation. -See [the `@web3-storage/capabilities` package](https://github.com/storacha/w3up/tree/main/packages/capabilities) for more information about capabilities and how they are defined in w3up services. +See [the `@storacha/capabilities` package](https://github.com/storacha/upload-service/tree/main/packages/capabilities) for more information about capabilities and how they are defined in w3up services. ### `CARMetadata` @@ -901,7 +915,7 @@ Delegations can be serialized by calling `export()` and piping the returned `Blo ### `Driver` -Storage drivers can be obtained from [`@web3-storage/access/stores`](https://github.com/storacha/w3up/tree/main/packages/access-client). They persist data created and managed by an agent. +Storage drivers can be obtained from [`@storacha/access/stores`](https://github.com/storacha/upload-service/tree/main/packages/access-client). They persist data created and managed by an agent. ### `ListResponse` @@ -970,19 +984,19 @@ interface UploadListResult { ## Contributing -Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/w3up/issues)! +Feel free to join in. All welcome. Please [open an issue](https://github.com/storacha/upload-service/issues)! ## License -Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/w3up/blob/main/packages/w3up-client/LICENSE.md) +Dual-licensed under [MIT + Apache 2.0](https://github.com/storacha/upload-service/blob/main/packages/w3up-client/LICENSE.md) [w3cli-github]: https://github.com/storacha/w3cli -[access-client-github]: https://github.com/storacha/w3up/tree/main/packages/access-client -[upload-client-github]: https://github.com/storacha/w3up/tree/main/packages/upload-client +[access-client-github]: https://github.com/storacha/upload-service/tree/main/packages/access-client +[upload-client-github]: https://github.com/storacha/upload-service/tree/main/packages/upload-client [elastic-ipfs]: https://github.com/elastic-ipfs/elastic-ipfs [ucanto]: https://github.com/storacha/ucanto [car-spec]: https://ipld.io/specs/transport/car/ -[web3storage-docs-cars]: https://web3.storage/docs/concepts/car/ +[web3storage-docs-cars]: https://docs.storacha.network/concepts/car/ [docs]: https://web3-storage.github.io/w3up/modules/_web3_storage_w3up_client.html [docs-Client]: https://web3-storage.github.io/w3up/classes/_web3_storage_w3up_client.Client.html diff --git a/packages/w3up-client/package.json b/packages/w3up-client/package.json index 11c7a2bfb..6bee1a520 100644 --- a/packages/w3up-client/package.json +++ b/packages/w3up-client/package.json @@ -1,7 +1,7 @@ { - "name": "@web3-storage/w3up-client", - "version": "16.4.0", - "description": "Client for the web3.storage w3up api", + "name": "@storacha/client", + "version": "1.1.4", + "description": "Client for the storacha.network w3up api", "license": "Apache-2.0 OR MIT", "type": "module", "main": "dist/src/index.js", @@ -32,6 +32,9 @@ "types": "./dist/src/account.d.ts", "import": "./dist/src/account.js" }, + "./browser.min.js": { + "default": "./browser.min.js" + }, "./delegation": { "types": "./dist/src/delegation.d.ts", "import": "./dist/src/delegation.js" @@ -80,10 +83,6 @@ "types": "./dist/src/capability/space.d.ts", "import": "./dist/src/capability/space.js" }, - "./capability/store": { - "types": "./dist/src/capability/store.d.ts", - "import": "./dist/src/capability/store.js" - }, "./capability/subscription": { "types": "./dist/src/capability/subscription.d.ts", "import": "./dist/src/capability/subscription.js" @@ -118,64 +117,73 @@ "access": "public" }, "files": [ - "dist" + "dist", + "*.min.js" ], "scripts": { "attw": "attw --pack .", "lint": "tsc --build && eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore", - "build": "tsc --build", + "lint:fix": "tsc --build && eslint '**/*.{js,ts}' --fix && prettier --write '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore", + "build": "npm run build:tsc && npm run build:bundle:browser", + "build:tsc": "tsc --build", + "build:bundle:browser": "esbuild src/index.js --bundle --minify --target=chrome130 --format=iife --global-name=StorachaClient --outfile=browser.min.js", "dev": "tsc --build --watch", "check": "tsc --build", "prepare": "npm run build", "test": "npm-run-all -p -r mock:* test:all", "test:all": "run-s test:node test:browser", - "test:node": "hundreds -r html -r text mocha 'test/**/!(*.browser).test.js' -n experimental-vm-modules -n no-warnings -n stack-trace-limit=1000 -t 10000", + "test:node": "hundreds -r html -r text mocha 'test/**/!(*.browser).test.js' -n experimental-vm-modules -n no-warnings -n stack-trace-limit=1000 -t 10000 --bail", "test:browser": "playwright-test --runner mocha 'test/**/!(*.node).test.js'", "mock": "run-p mock:*", - "mock:bucket-200": "PORT=8989 STATUS=200 node test/helpers/bucket-server.js", + "mock:bucket-0-200": "PORT=8989 STATUS=200 node test/helpers/bucket-server.js", + "mock:bucket-1-200": "PORT=8990 STATUS=200 node test/helpers/bucket-server.js", "mock:receipts-server": "PORT=9201 node test/helpers/receipts-server.js", + "mock:gateway-server": "PORT=5001 node test/helpers/gateway-server.js", "coverage": "c8 report -r html && open coverage/index.html", "rc": "npm version prerelease --preid rc", "docs": "npm run build && typedoc --out docs-generated" }, "dependencies": { - "@ipld/dag-ucan": "^3.4.0", + "@ipld/dag-ucan": "^3.4.5", + "@storacha/access": "workspace:^", + "@storacha/blob-index": "workspace:^", + "@storacha/capabilities": "workspace:^", + "@storacha/did-mailto": "workspace:^", + "@storacha/filecoin-client": "workspace:^", + "@storacha/upload-client": "workspace:^", "@ucanto/client": "^9.0.1", - "@ucanto/core": "^10.0.1", - "@ucanto/interface": "^10.0.1", - "@ucanto/principal": "^9.0.1", - "@ucanto/transport": "^9.1.1", - "@web3-storage/access": "workspace:^", - "@web3-storage/blob-index": "workspace:^", - "@web3-storage/capabilities": "workspace:^", - "@web3-storage/did-mailto": "workspace:^", - "@web3-storage/filecoin-client": "workspace:^", - "@web3-storage/upload-client": "workspace:^" + "@ucanto/core": "^10.2.1", + "@ucanto/interface": "^10.1.1", + "@ucanto/principal": "^9.0.2", + "@ucanto/transport": "^9.1.1" }, "devDependencies": { "@ipld/car": "^5.1.1", - "@ipld/unixfs": "^2.1.1", + "@ipld/unixfs": "^3.0.0", + "@storacha/eslint-config": "workspace:^", + "@storacha/upload-api": "workspace:^", "@types/assert": "^1.5.6", "@types/mocha": "^10.0.1", "@types/node": "^20.8.4", - "@ucanto/server": "^10.0.0", + "@ucanto/server": "^10.1.0", + "@web3-storage/access": "^20.1.0", "@web3-storage/content-claims": "^4.0.4", "@web3-storage/data-segment": "^5.0.0", - "@web3-storage/eslint-config-w3up": "workspace:^", - "@web3-storage/upload-api": "workspace:^", + "@web3-storage/w3up-client": "^16.5.1", "assert": "^2.0.0", "c8": "^7.13.0", + "esbuild": "^0.24.0", "hundreds": "^0.0.9", - "mocha": "^10.1.0", - "multiformats": "^12.1.2", + "mocha": "^10.8.2", + "multiformats": "^13.3.1", "npm-run-all": "^4.1.5", "playwright-test": "^12.3.4", "typedoc": "^0.25.3", - "typescript": "^5.2.2" + "typescript": "5.2.2" }, "eslintConfig": { "extends": [ - "@web3-storage/eslint-config-w3up" + "@storacha/eslint-config" ], "parserOptions": { "project": "./tsconfig.json" @@ -191,7 +199,8 @@ "docs", "docs-generated", "coverage", - "src/types.js" + "src/types.js", + "*.min.js" ] }, "directories": { @@ -199,7 +208,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/storacha/w3up.git", + "url": "https://github.com/storacha/upload-service.git", "directory": "packages/w3up-client" }, "keywords": [ @@ -214,9 +223,9 @@ ], "author": "DAG House", "bugs": { - "url": "https://github.com/storacha/w3up/issues" + "url": "https://github.com/storacha/upload-service/issues" }, - "homepage": "https://web3.storage", + "homepage": "https://storacha.network", "depcheck": { "ignorePatterns": [ "dist" diff --git a/packages/w3up-client/src/ability.js b/packages/w3up-client/src/ability.js index 062bd92a4..68452c024 100644 --- a/packages/w3up-client/src/ability.js +++ b/packages/w3up-client/src/ability.js @@ -1,4 +1,4 @@ -import { abilitiesAsStrings } from '@web3-storage/capabilities' +import { abilitiesAsStrings } from '@storacha/capabilities' const setOfAbilities = new Set(abilitiesAsStrings) @@ -12,13 +12,13 @@ const setOfAbilities = new Set(abilitiesAsStrings) * nice with Typescript. * * @param {string[]} abilities - * @returns {import('@web3-storage/capabilities/types').ServiceAbility[]} + * @returns {import('@storacha/capabilities/types').ServiceAbility[]} */ export function asAbilities(abilities) { for (const ability of abilities) { if ( !setOfAbilities.has( - /** @type {import('@web3-storage/capabilities/types').ServiceAbility} */ ( + /** @type {import('@storacha/capabilities/types').ServiceAbility} */ ( ability ) ) @@ -26,7 +26,7 @@ export function asAbilities(abilities) { throw new Error(`${ability} is not a supported capability`) } } - return /** @type {import('@web3-storage/capabilities/types').ServiceAbility[]} */ ( + return /** @type {import('@storacha/capabilities/types').ServiceAbility[]} */ ( abilities ) } diff --git a/packages/w3up-client/src/account.js b/packages/w3up-client/src/account.js index c6e418202..ababbfe48 100644 --- a/packages/w3up-client/src/account.js +++ b/packages/w3up-client/src/account.js @@ -2,14 +2,14 @@ import * as API from './types.js' import * as Access from './capability/access.js' import * as Plan from './capability/plan.js' import * as Subscription from './capability/subscription.js' -import { Delegation, importAuthorization } from '@web3-storage/access/agent' -import { add as provision, AccountDID } from '@web3-storage/access/provider' -import { fromEmail, toEmail } from '@web3-storage/did-mailto' +import { Delegation, importAuthorization } from '@storacha/access/agent' +import { add as provision, AccountDID } from '@storacha/access/provider' +import { fromEmail, toEmail } from '@storacha/did-mailto' export { fromEmail } /** - * @typedef {import('@web3-storage/did-mailto').EmailAddress} EmailAddress + * @typedef {import('@storacha/did-mailto').EmailAddress} EmailAddress */ /** @@ -242,10 +242,10 @@ export class AccountPlan { * or when the abort signal is aborted. * * @param {object} [options] - * @param {number} [options.interval=1000] - The polling interval in milliseconds (default is 1000ms). - * @param {number} [options.timeout=900000] - The maximum time to wait in milliseconds before throwing a timeout error (default is 15 minutes). + * @param {number} [options.interval] - The polling interval in milliseconds (default is 1000ms). + * @param {number} [options.timeout] - The maximum time to wait in milliseconds before throwing a timeout error (default is 15 minutes). * @param {AbortSignal} [options.signal] - An optional AbortSignal to cancel the waiting process. - * @returns {Promise} - Resolves once a payment plan is selected within the timeout. + * @returns {Promise} - Resolves once a payment plan is selected within the timeout. * @throws {Error} - Throws an error if there is an issue retrieving the payment plan or if the timeout is exceeded. */ async wait(options) { @@ -277,7 +277,7 @@ export class AccountPlan { /** * - * @param {import('@web3-storage/access').AccountDID} accountDID + * @param {import('@storacha/access').AccountDID} accountDID * @param {string} returnURL * @param {object} [options] * @param {string} [options.nonce] diff --git a/packages/w3up-client/src/base.js b/packages/w3up-client/src/base.js index 3d820a8d2..3ff5cb036 100644 --- a/packages/w3up-client/src/base.js +++ b/packages/w3up-client/src/base.js @@ -1,4 +1,4 @@ -import { Agent } from '@web3-storage/access/agent' +import { Agent } from '@storacha/access/agent' import { serviceConf, receiptsEndpoint } from './service.js' export class Base { @@ -15,7 +15,7 @@ export class Base { _serviceConf /** - * @param {import('@web3-storage/access').AgentData} agentData + * @param {import('@storacha/access').AgentData} agentData * @param {object} [options] * @param {import('./types.js').ServiceConf} [options.serviceConf] * @param {URL} [options.receiptsEndpoint] diff --git a/packages/w3up-client/src/capability/access.js b/packages/w3up-client/src/capability/access.js index ad97c99be..3aee0e763 100644 --- a/packages/w3up-client/src/capability/access.js +++ b/packages/w3up-client/src/capability/access.js @@ -1,6 +1,6 @@ import { Base } from '../base.js' -import * as Agent from '@web3-storage/access/agent' -import * as DIDMailto from '@web3-storage/did-mailto' +import * as Agent from '@storacha/access/agent' +import * as DIDMailto from '@storacha/did-mailto' import * as Result from '../result.js' import * as API from '../types.js' diff --git a/packages/w3up-client/src/capability/blob.js b/packages/w3up-client/src/capability/blob.js index 450fcfa4d..11bebce5d 100644 --- a/packages/w3up-client/src/capability/blob.js +++ b/packages/w3up-client/src/capability/blob.js @@ -1,5 +1,5 @@ -import { Blob } from '@web3-storage/upload-client' -import { Blob as BlobCapabilities } from '@web3-storage/capabilities' +import { Blob } from '@storacha/upload-client' +import { SpaceBlob as BlobCapabilities } from '@storacha/capabilities' import { sha256 } from 'multiformats/hashes/sha2' import { Base } from '../base.js' @@ -17,8 +17,12 @@ export class BlobClient extends Base { * @param {import('../types.js').RequestOptions} [options] */ async add(blob, options = {}) { + options = { + receiptsEndpoint: this._receiptsEndpoint.toString(), + connection: this._serviceConf.upload, + ...options, + } const conf = await this._invocationConfig([BlobCapabilities.add.can]) - options.connection = this._serviceConf.upload const bytes = new Uint8Array(await blob.arrayBuffer()) const digest = await sha256.digest(bytes) return { digest, ...(await Blob.add(conf, digest, bytes, options)) } diff --git a/packages/w3up-client/src/capability/filecoin.js b/packages/w3up-client/src/capability/filecoin.js index 54c8e3a02..7a88341e0 100644 --- a/packages/w3up-client/src/capability/filecoin.js +++ b/packages/w3up-client/src/capability/filecoin.js @@ -1,5 +1,5 @@ -import { Storefront } from '@web3-storage/filecoin-client' -import { Filecoin as FilecoinCapabilities } from '@web3-storage/capabilities' +import { Storefront } from '@storacha/filecoin-client' +import { Filecoin as FilecoinCapabilities } from '@storacha/capabilities' import { Base } from '../base.js' /** @@ -13,7 +13,7 @@ export class FilecoinClient extends Base { * - `filecoin/offer` * * @param {import('multiformats').UnknownLink} content - * @param {import('@web3-storage/capabilities/types').PieceLink} piece + * @param {import('@storacha/capabilities/types').PieceLink} piece * @param {object} [options] * @param {string} [options.nonce] */ @@ -31,7 +31,7 @@ export class FilecoinClient extends Base { * Required delegated capabilities: * - `filecoin/info` * - * @param {import('@web3-storage/capabilities/types').PieceLink} piece + * @param {import('@storacha/capabilities/types').PieceLink} piece * @param {object} [options] * @param {string} [options.nonce] */ diff --git a/packages/w3up-client/src/capability/index.js b/packages/w3up-client/src/capability/index.js index e963f1ec0..f849d2871 100644 --- a/packages/w3up-client/src/capability/index.js +++ b/packages/w3up-client/src/capability/index.js @@ -1,5 +1,5 @@ -import { Index } from '@web3-storage/upload-client' -import { Index as IndexCapabilities } from '@web3-storage/capabilities' +import { Index } from '@storacha/upload-client' +import { SpaceIndex as IndexCapabilities } from '@storacha/capabilities' import { Base } from '../base.js' /** diff --git a/packages/w3up-client/src/capability/plan.js b/packages/w3up-client/src/capability/plan.js index bdc1562b4..5fa2bac1f 100644 --- a/packages/w3up-client/src/capability/plan.js +++ b/packages/w3up-client/src/capability/plan.js @@ -1,13 +1,13 @@ import { Base } from '../base.js' import * as API from '../types.js' -import * as Plan from '@web3-storage/capabilities/plan' +import * as Plan from '@storacha/capabilities/plan' export class PlanClient extends Base { /** * Required delegated capabilities: * - `plan/get` * - * @param {import('@web3-storage/access').AccountDID} account + * @param {import('@storacha/access').AccountDID} account * @param {object} [options] * @param {string} [options.nonce] */ diff --git a/packages/w3up-client/src/capability/space.js b/packages/w3up-client/src/capability/space.js index f37d31fae..d21bfb50a 100644 --- a/packages/w3up-client/src/capability/space.js +++ b/packages/w3up-client/src/capability/space.js @@ -1,4 +1,6 @@ import { Base } from '../base.js' +import { Space as SpaceCapabilities } from '@storacha/capabilities' +import * as API from '../types.js' /** * Client for interacting with the `space/*` capabilities. @@ -17,4 +19,71 @@ export class SpaceClient extends Base { async info(space, options) { return await this._agent.getSpaceInfo(space, options) } + + /** + * Record egress data for a served resource. + * It will execute the capability invocation to find the customer and then record the egress data for the resource. + * + * Required delegated capabilities: + * - `space/content/serve/egress/record` + * + * @param {object} egressData + * @param {import('../types.js').SpaceDID} egressData.space + * @param {API.UnknownLink} egressData.resource + * @param {number} egressData.bytes + * @param {string} egressData.servedAt + * @param {object} [options] + * @param {string} [options.nonce] + * @param {API.Delegation[]} [options.proofs] + * @returns {Promise} + */ + async egressRecord(egressData, options) { + const out = await egressRecord( + { agent: this.agent }, + { ...egressData }, + { ...options } + ) + + if (!out.ok) { + throw new Error( + `failed ${SpaceCapabilities.egressRecord.can} invocation`, + { + cause: out.error, + } + ) + } + + return /** @type {API.EgressRecordSuccess} */ (out.ok) + } +} + +/** + * Record egress data for a resource from a given space. + * + * @param {{agent: API.Agent}} client + * @param {object} egressData + * @param {API.SpaceDID} egressData.space + * @param {API.UnknownLink} egressData.resource + * @param {number} egressData.bytes + * @param {string} egressData.servedAt + * @param {object} options + * @param {string} [options.nonce] + * @param {API.Delegation[]} [options.proofs] + */ +export const egressRecord = async ( + { agent }, + { space, resource, bytes, servedAt }, + { nonce, proofs = [] } +) => { + const receipt = await agent.invokeAndExecute(SpaceCapabilities.egressRecord, { + with: space, + proofs, + nonce, + nb: { + resource, + bytes, + servedAt: Math.floor(new Date(servedAt).getTime() / 1000), + }, + }) + return receipt.out } diff --git a/packages/w3up-client/src/capability/store.js b/packages/w3up-client/src/capability/store.js deleted file mode 100644 index 1f9a3f56d..000000000 --- a/packages/w3up-client/src/capability/store.js +++ /dev/null @@ -1,71 +0,0 @@ -import { Store } from '@web3-storage/upload-client' -import { Store as StoreCapabilities } from '@web3-storage/capabilities' -import { Base } from '../base.js' - -/** - * Client for interacting with the `store/*` capabilities. - */ -export class StoreClient extends Base { - /** - * Store a DAG encoded as a CAR file. - * - * Required delegated capabilities: - * - `store/add` - * - * @deprecated Use `client.capability.blob.add()` instead. - * @param {Blob} car - CAR file data. - * @param {import('../types.js').RequestOptions} [options] - */ - async add(car, options = {}) { - const conf = await this._invocationConfig([StoreCapabilities.add.can]) - options.connection = this._serviceConf.upload - return Store.add(conf, car, options) - } - - /** - * Get details of a stored item. - * - * Required delegated capabilities: - * - `store/get` - * - * @deprecated Use `client.capability.blob.get()` instead. - * @param {import('../types.js').CARLink} link - Root data CID for the DAG that was stored. - * @param {import('../types.js').RequestOptions} [options] - */ - async get(link, options = {}) { - const conf = await this._invocationConfig([StoreCapabilities.get.can]) - options.connection = this._serviceConf.upload - return Store.get(conf, link, options) - } - - /** - * List CAR files stored to the resource. - * - * Required delegated capabilities: - * - `store/list` - * - * @deprecated Use `client.capability.blob.list()` instead. - * @param {import('../types.js').ListRequestOptions} [options] - */ - async list(options = {}) { - const conf = await this._invocationConfig([StoreCapabilities.list.can]) - options.connection = this._serviceConf.upload - return Store.list(conf, options) - } - - /** - * Remove a stored CAR file by CAR CID. - * - * Required delegated capabilities: - * - `store/remove` - * - * @deprecated Use `client.capability.blob.remove()` instead. - * @param {import('../types.js').CARLink} link - CID of CAR file to remove. - * @param {import('../types.js').RequestOptions} [options] - */ - async remove(link, options = {}) { - const conf = await this._invocationConfig([StoreCapabilities.remove.can]) - options.connection = this._serviceConf.upload - return Store.remove(conf, link, options) - } -} diff --git a/packages/w3up-client/src/capability/subscription.js b/packages/w3up-client/src/capability/subscription.js index 6ef9d496e..f0f29370a 100644 --- a/packages/w3up-client/src/capability/subscription.js +++ b/packages/w3up-client/src/capability/subscription.js @@ -1,4 +1,4 @@ -import { Subscription as SubscriptionCapabilities } from '@web3-storage/capabilities' +import { Subscription as SubscriptionCapabilities } from '@storacha/capabilities' import * as API from '../types.js' import { Base } from '../base.js' @@ -12,7 +12,7 @@ export class SubscriptionClient extends Base { * Required delegated capabilities: * - `subscription/list` * - * @param {import('@web3-storage/access').AccountDID} account + * @param {import('@storacha/access').AccountDID} account * @param {object} [options] * @param {string} [options.nonce] */ diff --git a/packages/w3up-client/src/capability/upload.js b/packages/w3up-client/src/capability/upload.js index 5b709bf9d..57425ce4d 100644 --- a/packages/w3up-client/src/capability/upload.js +++ b/packages/w3up-client/src/capability/upload.js @@ -1,5 +1,5 @@ -import { Upload } from '@web3-storage/upload-client' -import { Upload as UploadCapabilities } from '@web3-storage/capabilities' +import { Upload } from '@storacha/upload-client' +import { Upload as UploadCapabilities } from '@storacha/capabilities' import { Base } from '../base.js' /** diff --git a/packages/w3up-client/src/capability/usage.js b/packages/w3up-client/src/capability/usage.js index 5685dd772..4c4c3d264 100644 --- a/packages/w3up-client/src/capability/usage.js +++ b/packages/w3up-client/src/capability/usage.js @@ -1,4 +1,4 @@ -import { Usage as UsageCapabilities } from '@web3-storage/capabilities' +import { Usage as UsageCapabilities } from '@storacha/capabilities' import * as API from '../types.js' import { Base } from '../base.js' @@ -31,37 +31,6 @@ export class UsageClient extends Base { return out.ok } - - /** - * Record egress data for a served resource. - * It will execute the capability invocation to find the customer and then record the egress data for the resource. - * - * Required delegated capabilities: - * - `usage/record` - * - * @param {import('../types.js').SpaceDID} space - * @param {object} egressData - * @param {API.UnknownLink} egressData.resource - * @param {number} egressData.bytes - * @param {string} egressData.servedAt - * @param {object} [options] - * @param {string} [options.nonce] - */ - async record(space, egressData, options) { - const out = await record( - { agent: this.agent }, - { space, ...egressData }, - { ...options } - ) - /* c8 ignore next 5 */ - if (!out.ok) { - throw new Error(`failed ${UsageCapabilities.record.can} invocation`, { - cause: out.error, - }) - } - - return out.ok - } } /** @@ -92,35 +61,3 @@ export const report = async ( }) return receipt.out } - -/** - * Record egress data for a resource from a given space. - * - * @param {{agent: API.Agent}} client - * @param {object} egressData - * @param {API.SpaceDID} egressData.space - * @param {API.UnknownLink} egressData.resource - * @param {number} egressData.bytes - * @param {string} egressData.servedAt - * @param {object} options - * @param {string} [options.nonce] - * @param {API.Delegation[]} [options.proofs] - * @returns {Promise>} - */ -export const record = async ( - { agent }, - { space, resource, bytes, servedAt }, - { nonce, proofs = [] } -) => { - const receipt = await agent.invokeAndExecute(UsageCapabilities.record, { - with: space, - proofs, - nonce, - nb: { - resource, - bytes, - servedAt: Math.floor(new Date(servedAt).getTime() / 1000), - }, - }) - return receipt.out -} diff --git a/packages/w3up-client/src/client.js b/packages/w3up-client/src/client.js index 89211ad7f..0d16c2a70 100644 --- a/packages/w3up-client/src/client.js +++ b/packages/w3up-client/src/client.js @@ -3,21 +3,22 @@ import { uploadDirectory, uploadCAR, Receipt, -} from '@web3-storage/upload-client' +} from '@storacha/upload-client' import { - Blob as BlobCapabilities, - Index as IndexCapabilities, + Access as AccessCapabilities, + SpaceBlob as BlobCapabilities, + SpaceIndex as IndexCapabilities, Upload as UploadCapabilities, Filecoin as FilecoinCapabilities, -} from '@web3-storage/capabilities' -import * as DIDMailto from '@web3-storage/did-mailto' + Space as SpaceCapabilities, +} from '@storacha/capabilities' +import * as DIDMailto from '@storacha/did-mailto' import { Base } from './base.js' import * as Account from './account.js' import { Space } from './space.js' import { AgentDelegation } from './delegation.js' import { BlobClient } from './capability/blob.js' import { IndexClient } from './capability/index.js' -import { StoreClient } from './capability/store.js' import { UploadClient } from './capability/upload.js' import { SpaceClient } from './capability/space.js' import { SubscriptionClient } from './capability/subscription.js' @@ -28,6 +29,9 @@ import { FilecoinClient } from './capability/filecoin.js' import { CouponAPI } from './coupon.js' export * as Access from './capability/access.js' import * as Result from './result.js' +import * as UcantoClient from '@ucanto/client' +import { HTTP } from '@ucanto/transport' +import * as CAR from '@ucanto/transport/car' export { AccessClient, @@ -35,7 +39,6 @@ export { FilecoinClient, IndexClient, PlanClient, - StoreClient, SpaceClient, SubscriptionClient, UploadClient, @@ -44,7 +47,7 @@ export { export class Client extends Base { /** - * @param {import('@web3-storage/access').AgentData} agentData + * @param {import('@storacha/access').AgentData} agentData * @param {object} [options] * @param {import('./types.js').ServiceConf} [options.serviceConf] * @param {URL} [options.receiptsEndpoint] @@ -58,7 +61,6 @@ export class Client extends Base { plan: new PlanClient(agentData, options), space: new SpaceClient(agentData, options), blob: new BlobClient(agentData, options), - store: new StoreClient(agentData, options), subscription: new SubscriptionClient(agentData, options), upload: new UploadClient(agentData, options), usage: new UsageClient(agentData, options), @@ -101,7 +103,7 @@ export class Client extends Base { /** * List all accounts that agent has stored access to. * - * @returns {Record} A dictionary with `did:mailto` as keys and `Account` instances as values. + * @returns {Record} A dictionary with `did:mailto` as keys and `Account` instances as values. */ accounts() { return Account.list(this) @@ -127,7 +129,11 @@ export class Client extends Base { FilecoinCapabilities.offer.can, UploadCapabilities.add.can, ]) - options.connection = this._serviceConf.upload + options = { + receiptsEndpoint: this._receiptsEndpoint.toString(), + connection: this._serviceConf.upload, + ...options, + } return uploadFile(conf, file, options) } @@ -152,7 +158,11 @@ export class Client extends Base { FilecoinCapabilities.offer.can, UploadCapabilities.add.can, ]) - options.connection = this._serviceConf.upload + options = { + receiptsEndpoint: this._receiptsEndpoint.toString(), + connection: this._serviceConf.upload, + ...options, + } return uploadDirectory(conf, files, options) } @@ -182,7 +192,11 @@ export class Client extends Base { FilecoinCapabilities.offer.can, UploadCapabilities.add.can, ]) - options.connection = this._serviceConf.upload + options = { + receiptsEndpoint: this._receiptsEndpoint.toString(), + connection: this._serviceConf.upload, + ...options, + } return uploadCAR(conf, car, options) } @@ -234,22 +248,32 @@ export class Client extends Base { } /** - * Create a new space with a given name. + * Creates a new space with a given name. * If an account is not provided, the space is created without any delegation and is not saved, hence it is a temporary space. * When an account is provided in the options argument, then it creates a delegated recovery account * by provisioning the space, saving it and then delegating access to the recovery account. + * In addition, it authorizes the listed Gateway Services to serve content from the created space. + * It is done by delegating the `space/content/serve/*` capability to the Gateway Service. + * User can skip the Gateway authorization by setting the `skipGatewayAuthorization` option to `true`. + * If no gateways are specified or the `skipGatewayAuthorization` flag is not set, the client will automatically grant access + * to the Storacha Gateway by default (https://w3s.link/). * - * @typedef {object} CreateOptions - * @property {Account.Account} [account] + * @typedef {import('./types.js').ConnectionView} ConnectionView * - * @param {string} name - * @param {CreateOptions} options + * @typedef {object} SpaceCreateOptions + * @property {Account.Account} [account] - The account configured as the recovery account for the space. + * @property {Array} [authorizeGatewayServices] - The DID Key or DID Web of the Gateway to authorize to serve content from the created space. + * @property {boolean} [skipGatewayAuthorization] - Whether to skip the Gateway authorization. It means that the content of the space will not be served by any Gateway. + * + * @param {string} name - The name of the space to create. + * @param {SpaceCreateOptions} [options] - Options for the space creation. * @returns {Promise} The created space owned by the agent. */ - async createSpace(name, options = {}) { + async createSpace(name, options) { + // Save the space to authorize the client to use the space const space = await this._agent.createSpace(name) - const account = options.account + const account = options?.account if (account) { // Provision the account with the space const provisionResult = await account.provision(space.did()) @@ -267,18 +291,52 @@ export class Client extends Base { const recovery = await space.createRecovery(account.did()) // Delegate space access to the recovery - const result = await this.capability.access.delegate({ + const delegationResult = await this.capability.access.delegate({ space: space.did(), delegations: [recovery], }) - if (result.error) { + if (delegationResult.error) { throw new Error( - `failed to authorize recovery account: ${result.error.message}`, - { cause: result.error } + `failed to authorize recovery account: ${delegationResult.error.message}`, + { cause: delegationResult.error } ) } } + + // Authorize the listed Gateway Services to serve content from the created space + if (!options || options.skipGatewayAuthorization !== true) { + let authorizeGatewayServices = options?.authorizeGatewayServices + if (!authorizeGatewayServices || authorizeGatewayServices.length === 0) { + // If no Gateway Services are provided, authorize the Storacha Gateway Service + authorizeGatewayServices = [ + UcantoClient.connect({ + id: { + did: () => + /** @type {`did:${string}:${string}`} */ ( + /* c8 ignore next - default prod gateway id is not used in tests */ + process.env.DEFAULT_GATEWAY_ID ?? 'did:web:w3s.link' + ), + }, + codec: CAR.outbound, + channel: HTTP.open({ + url: new URL( + /* c8 ignore next - default prod gateway url is not used in tests */ + process.env.DEFAULT_GATEWAY_URL ?? 'https://w3s.link' + ), + }), + }), + ] + } + + // Save the space to authorize the client to use the space + await space.save() + + for (const serviceConnection of authorizeGatewayServices) { + await authorizeContentServe(this, space, serviceConnection) + } + } + return space } @@ -315,10 +373,7 @@ export class Client extends Base { 'upload/*', 'access/*', 'usage/*', - 'filecoin/offer', - 'filecoin/info', - 'filecoin/accept', - 'filecoin/submit', + 'filecoin/*', ], expiration: Infinity, } @@ -488,24 +543,9 @@ export class Client extends Base { // Remove shards if (upload.shards?.length) { await Promise.allSettled( - upload.shards.map(async (shard) => { - try { - const res = await this.capability.blob.remove(shard.multihash) - /* c8 ignore start */ - // if no size, the blob was not found, try delete from store - if (res.ok && res.ok.size === 0) { - await this.capability.store.remove(shard) - } - } catch (/** @type {any} */ error) { - // If not found, we can tolerate error as it may be a consecutive call for deletion where first failed - if (error?.cause?.name !== 'StoreItemNotFound') { - throw new Error(`failed to remove shard: ${shard}`, { - cause: error, - }) - } - /* c8 ignore next 4 */ - } - }) + upload.shards.map((shard) => + this.capability.blob.remove(shard.multihash) + ) ) } @@ -513,3 +553,78 @@ export class Client extends Base { await this.capability.upload.remove(contentCID) } } + +/** + * Authorizes an audience to serve content from the provided space and record egress events. + * It also publishes the delegation to the content serve service. + * Delegates the following capabilities to the audience: + * - `space/content/serve/*` + * + * @param {Client} client - The w3up client instance. + * @param {import('./types.js').OwnedSpace} space - The space to authorize the audience for. + * @param {import('./types.js').ConnectionView} connection - The connection to the Content Serve Service that will handle, validate, and store the access/delegate UCAN invocation. + * @param {object} [options] - Options for the content serve authorization invocation. + * @param {`did:${string}:${string}`} [options.audience] - The Web DID of the audience (gateway or peer) to authorize. + * @param {number} [options.expiration] - The time at which the delegation expires in seconds from unix epoch. + */ +export const authorizeContentServe = async ( + client, + space, + connection, + options = {} +) => { + const currentSpace = client.currentSpace() + try { + // Set the current space to the space we are authorizing the gateway for, otherwise the delegation will fail + await client.setCurrentSpace(space.did()) + + /** @type {import('@ucanto/client').Principal<`did:${string}:${string}`>} */ + const audience = { + did: () => options.audience ?? connection.id.did(), + } + + // Grant the audience the ability to serve content from the space, it includes existing proofs automatically + const delegation = await client.createDelegation( + audience, + [SpaceCapabilities.contentServe.can], + { + expiration: options.expiration ?? Infinity, + } + ) + + // Publish the delegation to the content serve service + const accessProofs = client.proofs([ + { can: AccessCapabilities.access.can, with: space.did() }, + ]) + const verificationResult = await AccessCapabilities.delegate + .invoke({ + issuer: client.agent.issuer, + audience, + with: space.did(), + proofs: [...accessProofs, delegation], + nb: { + delegations: { + [delegation.cid.toString()]: delegation.cid, + }, + }, + }) + .execute(connection) + + /* c8 ignore next 8 - can't mock this error */ + if (verificationResult.out.error) { + throw new Error( + `failed to publish delegation for audience ${audience.did()}: ${ + verificationResult.out.error.message + }`, + { + cause: verificationResult.out.error, + } + ) + } + return { ok: { ...verificationResult.out.ok, delegation } } + } finally { + if (currentSpace) { + await client.setCurrentSpace(currentSpace.did()) + } + } +} diff --git a/packages/w3up-client/src/coupon.js b/packages/w3up-client/src/coupon.js index 0ca379c0d..505e9fd2b 100644 --- a/packages/w3up-client/src/coupon.js +++ b/packages/w3up-client/src/coupon.js @@ -1,8 +1,8 @@ -import * as API from '@web3-storage/access/types' +import * as API from '@storacha/access/types' import { sha256, delegate, Delegation } from '@ucanto/core' import { ed25519 } from '@ucanto/principal' import * as Result from './result.js' -import { GrantedAccess } from '@web3-storage/access/access' +import { GrantedAccess } from '@storacha/access/access' import { Base } from './base.js' export class CouponAPI extends Base { diff --git a/packages/w3up-client/src/index.js b/packages/w3up-client/src/index.js index 5d38b5363..a4d96eedc 100644 --- a/packages/w3up-client/src/index.js +++ b/packages/w3up-client/src/index.js @@ -1,17 +1,18 @@ /** - * The main entry point for the `@web3-storage/w3up-client` package. + * The main entry point for the `@storacha/client` package. * * Use the static {@link create} function to create a new {@link Client} object. * * @module */ -import { AgentData } from '@web3-storage/access/agent' -import { StoreIndexedDB } from '@web3-storage/access/stores/store-indexeddb' +import { AgentData } from '@storacha/access/agent' +import { StoreIndexedDB } from '@storacha/access/stores/store-indexeddb' import { generate } from '@ucanto/principal/rsa' import { Client } from './client.js' export * as Result from './result.js' export * as Account from './account.js' export * from './ability.js' +export { authorizeContentServe } from './client.js' /** * Create a new w3up client. diff --git a/packages/w3up-client/src/index.node.js b/packages/w3up-client/src/index.node.js index de24fcb9a..354aedbb1 100644 --- a/packages/w3up-client/src/index.node.js +++ b/packages/w3up-client/src/index.node.js @@ -2,8 +2,8 @@ * @hidden * @module */ -import { AgentData } from '@web3-storage/access/agent' -import { StoreConf } from '@web3-storage/access/stores/store-conf' +import { AgentData } from '@storacha/access/agent' +import { StoreConf } from '@storacha/access/stores/store-conf' import { generate } from '@ucanto/principal/ed25519' import { Client } from './client.js' export * as Result from './result.js' diff --git a/packages/w3up-client/src/service.js b/packages/w3up-client/src/service.js index adf19d84d..41bdec60c 100644 --- a/packages/w3up-client/src/service.js +++ b/packages/w3up-client/src/service.js @@ -1,42 +1,39 @@ import * as client from '@ucanto/client' import { CAR, HTTP } from '@ucanto/transport' import * as DID from '@ipld/dag-ucan/did' -import { receiptsEndpoint } from '@web3-storage/upload-client' +import { receiptsEndpoint } from '@storacha/upload-client' -export const accessServiceURL = new URL('https://up.web3.storage') -export const accessServicePrincipal = DID.parse('did:web:web3.storage') +export const accessServiceURL = new URL('https://upload.storacha.network') +export const accessServicePrincipal = DID.parse( + 'did:web:upload.storacha.network' +) export const accessServiceConnection = client.connect({ id: accessServicePrincipal, codec: CAR.outbound, - channel: HTTP.open({ - url: accessServiceURL, - method: 'POST', - }), + channel: HTTP.open({ url: accessServiceURL, method: 'POST' }), }) -export const uploadServiceURL = new URL('https://up.web3.storage') -export const uploadServicePrincipal = DID.parse('did:web:web3.storage') +export const uploadServiceURL = new URL('https://upload.storacha.network') +export const uploadServicePrincipal = DID.parse( + 'did:web:upload.storacha.network' +) export const uploadServiceConnection = client.connect({ id: uploadServicePrincipal, codec: CAR.outbound, - channel: HTTP.open({ - url: uploadServiceURL, - method: 'POST', - }), + channel: HTTP.open({ url: accessServiceURL, method: 'POST' }), }) -export const filecoinServiceURL = new URL('https://up.web3.storage') -export const filecoinServicePrincipal = DID.parse('did:web:web3.storage') +export const filecoinServiceURL = new URL('https://upload.storacha.network') +export const filecoinServicePrincipal = DID.parse( + 'did:web:upload.storacha.network' +) export const filecoinServiceConnection = client.connect({ id: filecoinServicePrincipal, codec: CAR.outbound, - channel: HTTP.open({ - url: filecoinServiceURL, - method: 'POST', - }), + channel: HTTP.open({ url: accessServiceURL, method: 'POST' }), }) /** @type {import('./types.js').ServiceConf} */ diff --git a/packages/w3up-client/src/space.js b/packages/w3up-client/src/space.js index b3bb2aa04..aa7207fd1 100644 --- a/packages/w3up-client/src/space.js +++ b/packages/w3up-client/src/space.js @@ -1,4 +1,4 @@ -export * from '@web3-storage/access/space' +export * from '@storacha/access/space' import * as Usage from './capability/usage.js' import * as API from './types.js' diff --git a/packages/w3up-client/src/stores/conf.js b/packages/w3up-client/src/stores/conf.js index 809a4eb06..5d56de34f 100644 --- a/packages/w3up-client/src/stores/conf.js +++ b/packages/w3up-client/src/stores/conf.js @@ -1 +1 @@ -export { StoreConf } from '@web3-storage/access/stores/store-conf' +export { StoreConf } from '@storacha/access/stores/store-conf' diff --git a/packages/w3up-client/src/stores/indexeddb.js b/packages/w3up-client/src/stores/indexeddb.js index 93a0e31ff..926485114 100644 --- a/packages/w3up-client/src/stores/indexeddb.js +++ b/packages/w3up-client/src/stores/indexeddb.js @@ -1 +1 @@ -export { StoreIndexedDB } from '@web3-storage/access/stores/store-indexeddb' +export { StoreIndexedDB } from '@storacha/access/stores/store-indexeddb' diff --git a/packages/w3up-client/src/stores/memory.js b/packages/w3up-client/src/stores/memory.js index 189451af6..eba79cadf 100644 --- a/packages/w3up-client/src/stores/memory.js +++ b/packages/w3up-client/src/stores/memory.js @@ -1 +1 @@ -export { StoreMemory } from '@web3-storage/access/stores/store-memory' +export { StoreMemory } from '@storacha/access/stores/store-memory' diff --git a/packages/w3up-client/src/types.ts b/packages/w3up-client/src/types.ts index 553c55e93..9ba80c48a 100644 --- a/packages/w3up-client/src/types.ts +++ b/packages/w3up-client/src/types.ts @@ -1,9 +1,12 @@ -import { type Driver } from '@web3-storage/access/drivers/types' +import { type Driver } from '@storacha/access/drivers/types' import { + AccessDelegate, + AccessDelegateFailure, + AccessDelegateSuccess, type Service as AccessService, type AgentDataExport, -} from '@web3-storage/access/types' -import { type Service as UploadService } from '@web3-storage/upload-client/types' +} from '@storacha/access/types' +import { type Service as UploadService } from '@storacha/upload-client/types' import type { ConnectionView, Signer, @@ -11,12 +14,13 @@ import type { Ability, Resource, Unit, + ServiceMethod, } from '@ucanto/interface' import { type Client } from './client.js' -import { StorefrontService } from '@web3-storage/filecoin-client/storefront' +import { StorefrontService } from '@storacha/filecoin-client/storefront' export * from '@ucanto/interface' -export * from '@web3-storage/did-mailto' -export type { Agent, CapabilityQuery } from '@web3-storage/access/agent' +export * from '@storacha/did-mailto' +export type { Agent, CapabilityQuery } from '@storacha/access/agent' export type { Access, AccountDID, @@ -24,7 +28,7 @@ export type { SpaceDID, OwnedSpace, SharedSpace, -} from '@web3-storage/access/types' +} from '@storacha/access/types' export type ProofQuery = Record> @@ -36,6 +40,15 @@ export interface ServiceConf { filecoin: ConnectionView } +export interface ContentServeService { + access: { + delegate: ServiceMethod< + AccessDelegate, + AccessDelegateSuccess, + AccessDelegateFailure + > + } +} export interface ClientFactoryOptions { /** * A storage driver that persists exported agent data. @@ -79,9 +92,9 @@ export type { export type { Abilities, ServiceAbility, - BlobAdd, - BlobList, - BlobRemove, + SpaceBlobAdd, + SpaceBlobList, + SpaceBlobRemove, StoreAdd, StoreList, StoreRemove, @@ -109,30 +122,24 @@ export type { FilecoinInfo, FilecoinInfoSuccess, FilecoinInfoFailure, -} from '@web3-storage/capabilities/types' +} from '@storacha/capabilities/types' export type { AgentDataModel, AgentDataExport, AgentMeta, DelegationMeta, -} from '@web3-storage/access/types' +} from '@storacha/access/types' export type { - BlobAddSuccess, - BlobAddFailure, - BlobListSuccess, - BlobListFailure, - BlobRemoveSuccess, - BlobRemoveFailure, - IndexAddSuccess, - IndexAddFailure, - StoreAddSuccess, - StoreGetSuccess, - StoreGetFailure, - StoreRemoveSuccess, - StoreRemoveFailure, - StoreListSuccess, + SpaceBlobAddSuccess, + SpaceBlobAddFailure, + SpaceBlobListSuccess, + SpaceBlobListFailure, + SpaceBlobRemoveSuccess, + SpaceBlobRemoveFailure, + SpaceIndexAddSuccess, + SpaceIndexAddFailure, UploadAddSuccess, UploadGetSuccess, UploadGetFailure, @@ -164,4 +171,4 @@ export type { FileLike, BlobLike, ProgressStatus, -} from '@web3-storage/upload-client/types' +} from '@storacha/upload-client/types' diff --git a/packages/w3up-client/test/ability.test.js b/packages/w3up-client/test/ability.test.js index fce89459f..778d52de3 100644 --- a/packages/w3up-client/test/ability.test.js +++ b/packages/w3up-client/test/ability.test.js @@ -1,4 +1,4 @@ -import { asAbilities } from '@web3-storage/w3up-client' +import { asAbilities } from '@storacha/client' import * as Test from './test.js' /** diff --git a/packages/w3up-client/test/account.test.js b/packages/w3up-client/test/account.test.js index 573907b6c..b53542441 100644 --- a/packages/w3up-client/test/account.test.js +++ b/packages/w3up-client/test/account.test.js @@ -111,7 +111,9 @@ export const testAccount = Test.withContext({ assert, { client, mail, grantAccess } ) => { - const space = await client.createSpace('test') + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) const mnemonic = space.toMnemonic() const { signer } = await Space.fromMnemonic(mnemonic, { name: 'import' }) assert.deepEqual( @@ -147,7 +149,9 @@ export const testAccount = Test.withContext({ 'multi device workflow': async (asserts, { connect, mail, grantAccess }) => { const laptop = await connect() - const space = await laptop.createSpace('main') + const space = await laptop.createSpace('main', { + skipGatewayAuthorization: true, + }) // want to provision space ? const email = 'alice@web.mail' @@ -183,7 +187,9 @@ export const testAccount = Test.withContext({ asserts.deepEqual(result.did, space.did()) }, 'setup recovery': async (assert, { client, mail, grantAccess }) => { - const space = await client.createSpace('test') + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) const email = 'alice@web.mail' const login = Account.login(client, email) @@ -236,19 +242,19 @@ export const testAccount = Test.withContext({ await plansStorage.initialize( account.did(), 'stripe:123xyz', - 'did:web:free.web3.storage' + 'did:web:free.storacha.network' ) ) const { ok: plan } = await account.plan.get({ nonce: '2' }) - assert.ok(plan?.product, 'did:web:free.web3.storage') + assert.ok(plan?.product, 'did:web:free.storacha.network') - Result.unwrap(await account.plan.set('did:web:lite.web3.storage')) + Result.unwrap(await account.plan.set('did:web:lite.storacha.network')) const { ok: newPlan } = await account.plan.get({ nonce: '3' }) - assert.ok(newPlan?.product, 'did:web:lite.web3.storage') + assert.ok(newPlan?.product, 'did:web:lite.storacha.network') }, 'create plan admin session': async ( @@ -280,7 +286,9 @@ export const testAccount = Test.withContext({ assert, { client, mail, grantAccess } ) => { - const space = await client.createSpace('test') + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) const email = 'alice@web.mail' const login = Account.login(client, email) @@ -299,8 +307,10 @@ export const testAccount = Test.withContext({ assert.equal(typeof subs.results[0].subscription, 'string') }, - 'space.save': async (assert, { client, mail, grantAccess }) => { - const space = await client.createSpace('test') + 'space.save': async (assert, { client }) => { + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) assert.deepEqual(client.spaces(), []) const result = await space.save() diff --git a/packages/w3up-client/test/capability/access.test.js b/packages/w3up-client/test/capability/access.test.js index 61702a9ff..82b5f1b4e 100644 --- a/packages/w3up-client/test/capability/access.test.js +++ b/packages/w3up-client/test/capability/access.test.js @@ -1,6 +1,6 @@ -import { AgentData } from '@web3-storage/access/agent' +import { AgentData } from '@storacha/access/agent' import { Client } from '../../src/client.js' -import * as Upload from '@web3-storage/capabilities/upload' +import * as Upload from '@storacha/capabilities/upload' import * as Test from '../test.js' export const AccessClient = Test.withContext({ @@ -20,7 +20,7 @@ export const AccessClient = Test.withContext({ }, 'should delegate and then claim': async ( assert, - { connection, provisionsStorage } + { id: w3, connection, provisionsStorage } ) => { const alice = new Client(await AgentData.create(), { // @ts-ignore @@ -29,7 +29,10 @@ export const AccessClient = Test.withContext({ upload: connection, }, }) - const space = await alice.createSpace('upload-test') + + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) diff --git a/packages/w3up-client/test/capability/blob.test.js b/packages/w3up-client/test/capability/blob.test.js index 1baacf1ff..f380116ae 100644 --- a/packages/w3up-client/test/capability/blob.test.js +++ b/packages/w3up-client/test/capability/blob.test.js @@ -1,14 +1,15 @@ import { sha256 } from 'multiformats/hashes/sha2' -import { AgentData } from '@web3-storage/access/agent' +import { AgentData } from '@storacha/access/agent' import { randomBytes } from '../helpers/random.js' import { Client } from '../../src/client.js' import * as Test from '../test.js' import { receiptsEndpoint } from '../helpers/utils.js' +import * as Result from '../helpers/result.js' export const BlobClient = Test.withContext({ 'should store a blob': async ( assert, - { connection, provisionsStorage, allocationsStorage } + { connection, provisionsStorage, registry } ) => { const alice = new Client(await AgentData.create(), { // @ts-ignore @@ -16,9 +17,12 @@ export const BlobClient = Test.withContext({ access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -33,14 +37,10 @@ export const BlobClient = Test.withContext({ const bytes = await randomBytes(128) const bytesHash = await sha256.digest(bytes) - const { digest } = await alice.capability.blob.add(new Blob([bytes]), { - receiptsEndpoint, - }) + const { digest } = await alice.capability.blob.add(new Blob([bytes])) // TODO we should check blobsStorage as well - assert.deepEqual(await allocationsStorage.exists(space.did(), digest), { - ok: true, - }) + Result.try(await registry.find(space.did(), digest)) assert.deepEqual(digest.bytes, bytesHash.bytes) }, @@ -54,9 +54,12 @@ export const BlobClient = Test.withContext({ access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -71,9 +74,7 @@ export const BlobClient = Test.withContext({ const bytes = await randomBytes(128) const bytesHash = await sha256.digest(bytes) - const { digest } = await alice.capability.blob.add(new Blob([bytes]), { - receiptsEndpoint, - }) + const { digest } = await alice.capability.blob.add(new Blob([bytes])) assert.deepEqual(digest.bytes, bytesHash.bytes) const { @@ -93,9 +94,12 @@ export const BlobClient = Test.withContext({ access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -109,9 +113,7 @@ export const BlobClient = Test.withContext({ }) const bytes = await randomBytes(128) - const { digest } = await alice.capability.blob.add(new Blob([bytes]), { - receiptsEndpoint, - }) + const { digest } = await alice.capability.blob.add(new Blob([bytes])) const result = await alice.capability.blob.remove(digest) assert.ok(result.ok) @@ -126,9 +128,12 @@ export const BlobClient = Test.withContext({ access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -142,9 +147,7 @@ export const BlobClient = Test.withContext({ }) const bytes = await randomBytes(128) - const { digest } = await alice.capability.blob.add(new Blob([bytes]), { - receiptsEndpoint, - }) + const { digest } = await alice.capability.blob.add(new Blob([bytes])) const result = await alice.capability.blob.get(digest) assert.ok(result.ok) diff --git a/packages/w3up-client/test/capability/filecoin.test.js b/packages/w3up-client/test/capability/filecoin.test.js index f2640bece..1bd1b855c 100644 --- a/packages/w3up-client/test/capability/filecoin.test.js +++ b/packages/w3up-client/test/capability/filecoin.test.js @@ -1,11 +1,13 @@ -import { Filecoin as FilecoinCapabilities } from '@web3-storage/capabilities' +import { Filecoin as FilecoinCapabilities } from '@storacha/capabilities' import { randomAggregate, randomCAR, randomCargo } from '../helpers/random.js' import * as Test from '../test.js' export const FilecoinClient = Test.withContext({ offer: { 'should send an offer': async (assert, { client: alice }) => { - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -36,7 +38,9 @@ export const FilecoinClient = Test.withContext({ throw new Error('could not compute proof') } - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) diff --git a/packages/w3up-client/test/capability/index.test.js b/packages/w3up-client/test/capability/index.test.js index 40196272c..8ac02dd06 100644 --- a/packages/w3up-client/test/capability/index.test.js +++ b/packages/w3up-client/test/capability/index.test.js @@ -1,4 +1,4 @@ -import { ShardedDAGIndex } from '@web3-storage/blob-index' +import { ShardedDAGIndex } from '@storacha/blob-index' import { codec as CAR } from '@ucanto/transport/car' import * as Link from 'multiformats/link' import * as Result from '../../src/result.js' @@ -14,7 +14,9 @@ export const IndexClient = Test.withContext({ ) => { const car = await randomCAR(128) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) diff --git a/packages/w3up-client/test/capability/plan.test.js b/packages/w3up-client/test/capability/plan.test.js index f75cbc89b..9bba03f7f 100644 --- a/packages/w3up-client/test/capability/plan.test.js +++ b/packages/w3up-client/test/capability/plan.test.js @@ -5,7 +5,7 @@ import * as Result from '../../src/result.js' /** * * @param {*} client - * @param {import('@web3-storage/upload-api').DebugEmail} mail + * @param {import('@storacha/upload-api').DebugEmail} mail * @param {(email: {url: string | URL}) => Promise} grantAccess */ async function initializeAccount(client, mail, grantAccess) { diff --git a/packages/w3up-client/test/capability/space.test.js b/packages/w3up-client/test/capability/space.test.js index 8e9bcc4b1..5ae3af329 100644 --- a/packages/w3up-client/test/capability/space.test.js +++ b/packages/w3up-client/test/capability/space.test.js @@ -1,6 +1,9 @@ -import { AgentData } from '@web3-storage/access/agent' +import { AgentData } from '@storacha/access/agent' import { Client } from '../../src/client.js' import * as Test from '../test.js' +import { Space } from '@storacha/capabilities' +import { gatewaySigner } from '../../../upload-api/test/helpers/utils.js' +import { randomCAR } from '../helpers/random.js' export const SpaceClient = Test.withContext({ info: { @@ -16,7 +19,9 @@ export const SpaceClient = Test.withContext({ }, }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice, { access: { 'space/info': {} }, expiration: Infinity, @@ -37,6 +42,554 @@ export const SpaceClient = Test.withContext({ assert.deepEqual(info.providers, [connection.id.did()]) }, }, + record: { + 'should record egress if the capability is derived from *': async ( + assert, + { id: w3, connection, provisionsStorage } + ) => { + const expiration = Date.now() + 1000 * 60 * 60 * 24 // 1 day from now + + // 1. Setup test space and allow Alice Agent to access it + const alice = new Client(await AgentData.create(), { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + }) + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) + const auth = await alice.addSpace(await space.createAuthorization(alice)) + assert.ok(auth) + + await alice.setCurrentSpace(space.did()) + await provisionsStorage.put({ + // @ts-expect-error + provider: w3.did(), + account: alice.did(), + consumer: space.did(), + }) + + // 2. Creates a new agent using freewaySigner as the principal + const freewayService = new Client( + await AgentData.create({ + principal: gatewaySigner, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + // 3. Alice delegates to the Gateway the ability to record egress + const egressRecordGatewayDelegation = await Space.egressRecord.delegate({ + issuer: alice.agent.issuer, + audience: freewayService, + with: space.did(), + expiration: expiration, + proofs: await alice.proofs(), + }) + + const resultDelegation2 = await alice.capability.access.delegate({ + delegations: [egressRecordGatewayDelegation], + }) + assert.ok(resultDelegation2.ok) + + // 4. freewayService claims the delegation + const freewayDelegations = await freewayService.capability.access.claim() + assert.ok(freewayDelegations.length > 0) + assert.ok( + freewayDelegations.some( + (d) => + d.issuer.did() === alice.did() && + d.audience.did() === freewayService.did() && + d.capabilities.some( + (c) => c.can === Space.egressRecord.can && c.with === space.did() + ) + ) + ) + + // 5. Create a random resource to record egress + const car = await randomCAR(128) + const resource = car.cid + assert.ok(resource) + + // 6. freewayService invokes egress/record + try { + const egressData = { + space: space.did(), + resource: resource.link(), + bytes: car.size, + servedAt: new Date().toISOString(), + } + const egressRecord = await freewayService.capability.space.egressRecord( + egressData, + { + proofs: await freewayService.proofs(), + } + ) + assert.ok(egressRecord, 'egressRecord should be returned') + assert.equal( + egressRecord.space, + space.did(), + 'space should be the same' + ) + assert.equal( + egressRecord.resource.toString(), + resource.toString(), + 'resource should be the same' + ) + assert.equal(egressRecord.bytes, car.size, 'bytes should be the same') + assert.equal( + new Date(egressRecord.servedAt).getTime(), + Math.floor(new Date(egressData.servedAt).getTime() / 1000), + 'servedAt should be the same' + ) + assert.ok(egressRecord.cause.toString(), 'cause should be a link') + } catch (error) { + // @ts-ignore + assert.fail(error.cause ? error.cause.message : error) + } + }, + 'should record egress if the capability is derived from space/*': async ( + assert, + { id: w3, connection, provisionsStorage } + ) => { + const expiration = Date.now() + 1000 * 60 * 60 * 24 // 1 day from now + + // 1. Setup test space and allow Alice Agent to access it + const alice = new Client(await AgentData.create(), { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + }) + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) + const auth = await alice.addSpace(await space.createAuthorization(alice)) + assert.ok(auth) + + await alice.setCurrentSpace(space.did()) + await provisionsStorage.put({ + // @ts-expect-error + provider: w3.did(), + account: alice.did(), + consumer: space.did(), + }) + + // 2. Creates a new agent using freewaySigner as the principal + const freewayService = new Client( + await AgentData.create({ + principal: gatewaySigner, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + // 3. Alice delegates to the Gateway the ability to record egress + const spaceAccessGatewayDelegation = await Space.top.delegate({ + issuer: alice.agent.issuer, + audience: freewayService, + with: space.did(), + expiration: expiration, + proofs: await alice.proofs(), + }) + + const resultDelegation2 = await alice.capability.access.delegate({ + delegations: [spaceAccessGatewayDelegation], + }) + assert.ok(resultDelegation2.ok) + + // 4. freewayService claims the delegation + const freewayDelegations = await freewayService.capability.access.claim() + assert.ok(freewayDelegations.length > 0) + assert.ok( + freewayDelegations.some( + (d) => + d.issuer.did() === alice.did() && + d.audience.did() === freewayService.did() && + d.capabilities.some( + (c) => c.can === Space.top.can && c.with === space.did() + ) + ) + ) + + // 5. Create a random resource to record egress + const car = await randomCAR(128) + const resource = car.cid + assert.ok(resource) + + // 6. freewayService invokes egress/record + try { + const egressData = { + space: space.did(), + resource: resource.link(), + bytes: car.size, + servedAt: new Date().toISOString(), + } + const egressRecord = await freewayService.capability.space.egressRecord( + egressData, + { + proofs: await freewayService.proofs(), + } + ) + assert.ok(egressRecord, 'egressRecord should be returned') + assert.equal( + egressRecord.space, + space.did(), + 'space should be the same' + ) + assert.equal( + egressRecord.resource.toString(), + resource.toString(), + 'resource should be the same' + ) + assert.equal(egressRecord.bytes, car.size, 'bytes should be the same') + assert.equal( + new Date(egressRecord.servedAt).getTime(), + Math.floor(new Date(egressData.servedAt).getTime() / 1000), + 'servedAt should be the same' + ) + assert.ok(egressRecord.cause.toString(), 'cause should be a link') + } catch (error) { + // @ts-ignore + assert.fail(error.cause ? error.cause.message : error) + } + }, + 'should record egress if the capability is derived from space/content/serve/*': + async (assert, { id: w3, connection, provisionsStorage }) => { + const expiration = Date.now() + 1000 * 60 * 60 * 24 // 1 day from now + + // 1. Setup test space and allow Alice Agent to access it + const alice = new Client(await AgentData.create(), { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + }) + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) + const auth = await alice.addSpace( + await space.createAuthorization(alice) + ) + assert.ok(auth) + + await alice.setCurrentSpace(space.did()) + await provisionsStorage.put({ + // @ts-expect-error + provider: w3.did(), + account: alice.did(), + consumer: space.did(), + }) + + // 2. Creates a new agent using freewaySigner as the principal + const freewayService = new Client( + await AgentData.create({ + principal: gatewaySigner, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + // 3. Alice delegates to the Gateway the ability to serve content + const contentServeGatewayDelegation = await Space.contentServe.delegate( + { + issuer: alice.agent.issuer, + audience: freewayService, + with: space.did(), + expiration: expiration, + proofs: await alice.proofs(), + } + ) + + const resultDelegation2 = await alice.capability.access.delegate({ + delegations: [contentServeGatewayDelegation], + }) + assert.ok(resultDelegation2.ok) + + // 4. freewayService claims the delegation + const freewayDelegations = + await freewayService.capability.access.claim() + assert.ok(freewayDelegations.length > 0) + assert.ok( + freewayDelegations.some( + (d) => + d.issuer.did() === alice.did() && + d.audience.did() === freewayService.did() && + d.capabilities.some( + (c) => + c.can === Space.contentServe.can && c.with === space.did() + ) + ) + ) + + // 5. Create a random resource to record egress + const car = await randomCAR(128) + const resource = car.cid + assert.ok(resource) + + // 6. freewayService invokes egress/record + try { + const egressData = { + space: space.did(), + resource: resource.link(), + bytes: car.size, + servedAt: new Date().toISOString(), + } + const egressRecord = + await freewayService.capability.space.egressRecord(egressData, { + proofs: await freewayService.proofs(), + }) + assert.ok(egressRecord, 'egressRecord should be returned') + assert.equal( + egressRecord.space, + space.did(), + 'space should be the same' + ) + assert.equal( + egressRecord.resource.toString(), + resource.toString(), + 'resource should be the same' + ) + assert.equal(egressRecord.bytes, car.size, 'bytes should be the same') + assert.equal( + new Date(egressRecord.servedAt).getTime(), + Math.floor(new Date(egressData.servedAt).getTime() / 1000), + 'servedAt should be the same' + ) + assert.ok(egressRecord.cause.toString(), 'cause should be a link') + } catch (error) { + // @ts-ignore + assert.fail(error.cause ? error.cause.message : error) + } + }, + 'should record egress if the capability space/content/serve/egress/record is delegated': + async (assert, { id: w3, connection, provisionsStorage }) => { + const expiration = Date.now() + 1000 * 60 * 60 * 24 // 1 day from now + + // 1. Setup test space and allow Alice Agent to access it + const alice = new Client(await AgentData.create(), { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + }) + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) + const auth = await alice.addSpace( + await space.createAuthorization(alice) + ) + assert.ok(auth) + + await alice.setCurrentSpace(space.did()) + await provisionsStorage.put({ + // @ts-expect-error + provider: w3.did(), + account: alice.did(), + consumer: space.did(), + }) + + // 2. Creates a new agent using freewaySigner as the principal + const freewayService = new Client( + await AgentData.create({ + principal: gatewaySigner, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + // 3. Alice delegates to the Gateway the ability to record egress + const egressRecordGatewayDelegation = await Space.egressRecord.delegate( + { + issuer: alice.agent.issuer, + audience: freewayService, + with: space.did(), + expiration: expiration, + proofs: await alice.proofs(), + } + ) + + const resultDelegation2 = await alice.capability.access.delegate({ + delegations: [egressRecordGatewayDelegation], + }) + assert.ok(resultDelegation2.ok) + + // 4. freewayService claims the delegation + const freewayDelegations = + await freewayService.capability.access.claim() + assert.ok(freewayDelegations.length > 0) + assert.ok( + freewayDelegations.some( + (d) => + d.issuer.did() === alice.did() && + d.audience.did() === freewayService.did() && + d.capabilities.some( + (c) => + c.can === Space.egressRecord.can && c.with === space.did() + ) + ) + ) + + // 5. Create a random resource to record egress + const car = await randomCAR(128) + const resource = car.cid + assert.ok(resource) + + // 6. freewayService invokes egress/record + try { + const egressData = { + space: space.did(), + resource: resource.link(), + bytes: car.size, + servedAt: new Date().toISOString(), + } + const egressRecord = + await freewayService.capability.space.egressRecord(egressData, { + proofs: await freewayService.proofs(), + }) + assert.ok(egressRecord, 'egressRecord should be returned') + assert.equal( + egressRecord.space, + space.did(), + 'space should be the same' + ) + assert.equal( + egressRecord.resource.toString(), + resource.toString(), + 'resource should be the same' + ) + assert.equal(egressRecord.bytes, car.size, 'bytes should be the same') + assert.equal( + new Date(egressRecord.servedAt).getTime(), + Math.floor(new Date(egressData.servedAt).getTime() / 1000), + 'servedAt should be the same' + ) + assert.ok(egressRecord.cause.toString(), 'cause should be a link') + } catch (error) { + // @ts-ignore + assert.fail(error.cause ? error.cause.message : error) + } + }, + 'should fail to record egress if the capability was not delegated': async ( + assert, + { id: w3, connection, provisionsStorage } + ) => { + const expiration = Date.now() + 1000 * 60 * 60 * 24 // 1 day from now + + // 1. Setup test space and allow Alice Agent to access it + const alice = new Client(await AgentData.create(), { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + }) + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) + const auth = await alice.addSpace(await space.createAuthorization(alice)) + assert.ok(auth) + + await alice.setCurrentSpace(space.did()) + await provisionsStorage.put({ + // @ts-expect-error + provider: w3.did(), + account: alice.did(), + consumer: space.did(), + }) + + // 2. Creates a new agent using freewaySigner as the principal + const freewayService = new Client( + await AgentData.create({ + principal: gatewaySigner, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + // 3. Alice delegates to the Gateway the ability to record egress but without proofs + const egressRecordGatewayDelegation = await Space.egressRecord.delegate({ + issuer: alice.agent.issuer, + audience: freewayService, + with: space.did(), + expiration: expiration, + proofs: [], // No proofs to test the error + }) + + const resultDelegation2 = await alice.capability.access.delegate({ + delegations: [egressRecordGatewayDelegation], + }) + assert.ok(resultDelegation2.ok) + + // 4. freewayService claims the delegation + const freewayDelegations = await freewayService.capability.access.claim() + assert.ok(freewayDelegations.length > 0) + assert.ok( + freewayDelegations.some( + (d) => + d.issuer.did() === alice.did() && + d.audience.did() === freewayService.did() && + d.capabilities.some( + (c) => c.can === Space.egressRecord.can && c.with === space.did() + ) + ) + ) + + // 5. Create a random resource to record egress + const car = await randomCAR(128) + + // 6. FreewayService attempts to invoke egress/record without having the delegation + try { + await freewayService.capability.space.egressRecord( + { + space: space.did(), + resource: car.cid.link(), + bytes: car.size, + servedAt: new Date().toISOString(), + }, + { proofs: [] } + ) + assert.fail('Expected an error due to missing delegation') + } catch (error) { + assert.equal( + // @ts-ignore + error.message, + `failed ${Space.egressRecord.can} invocation`, + 'error message should be the same' + ) + } + }, + }, }) Test.test({ SpaceClient }) diff --git a/packages/w3up-client/test/capability/store.test.js b/packages/w3up-client/test/capability/store.test.js deleted file mode 100644 index 602a46602..000000000 --- a/packages/w3up-client/test/capability/store.test.js +++ /dev/null @@ -1,147 +0,0 @@ -import { AgentData } from '@web3-storage/access/agent' -import { randomCAR } from '../helpers/random.js' -import { Client } from '../../src/client.js' -import * as Test from '../test.js' - -export const StoreClient = Test.withContext({ - 'should store a CAR file': async ( - assert, - { connection, provisionsStorage, storeTable } - ) => { - const alice = new Client(await AgentData.create(), { - // @ts-ignore - serviceConf: { - access: connection, - upload: connection, - }, - }) - - const space = await alice.createSpace('test') - const auth = await space.createAuthorization(alice) - await alice.addSpace(auth) - await alice.setCurrentSpace(space.did()) - - // Then we setup a billing for this account - await provisionsStorage.put({ - // @ts-expect-error - provider: connection.id.did(), - account: alice.agent.did(), - consumer: space.did(), - }) - - const car = await randomCAR(128) - const carCID = await alice.capability.store.add(car) - - assert.deepEqual(await storeTable.exists(space.did(), car.cid), { - ok: true, - }) - - assert.equal(carCID.toString(), car.cid.toString()) - }, - - 'should list stored CARs': async ( - assert, - { connection, provisionsStorage, storeTable } - ) => { - const alice = new Client(await AgentData.create(), { - // @ts-ignore - serviceConf: { - access: connection, - upload: connection, - }, - }) - - const space = await alice.createSpace('test') - const auth = await space.createAuthorization(alice) - await alice.addSpace(auth) - await alice.setCurrentSpace(space.did()) - - // Then we setup a billing for this account - await provisionsStorage.put({ - // @ts-expect-error - provider: connection.id.did(), - account: alice.agent.did(), - consumer: space.did(), - }) - - const car = await randomCAR(128) - const carCID = await alice.capability.store.add(car) - assert.deepEqual(carCID, car.cid) - - const { - results: [entry], - } = await alice.capability.store.list() - - assert.deepEqual(entry.link, car.cid) - assert.deepEqual(entry.size, car.size) - }, - 'should remove a stored CAR': async ( - assert, - { connection, provisionsStorage } - ) => { - const alice = new Client(await AgentData.create(), { - // @ts-ignore - serviceConf: { - access: connection, - upload: connection, - }, - }) - - const space = await alice.createSpace('test') - const auth = await space.createAuthorization(alice) - await alice.addSpace(auth) - await alice.setCurrentSpace(space.did()) - - // Then we setup a billing for this account - await provisionsStorage.put({ - // @ts-expect-error - provider: connection.id.did(), - account: alice.agent.did(), - consumer: space.did(), - }) - - const car = await randomCAR(128) - const cid = await alice.capability.store.add(car) - - const result = await alice.capability.store.remove(cid) - assert.ok(result.ok) - }, - - 'should get a stored item': async ( - assert, - { connection, provisionsStorage } - ) => { - const car = await randomCAR(128) - - const alice = new Client(await AgentData.create(), { - // @ts-ignore - serviceConf: { - access: connection, - upload: connection, - }, - }) - - const space = await alice.createSpace('test') - const auth = await space.createAuthorization(alice) - await alice.addSpace(auth) - await alice.setCurrentSpace(space.did()) - - // Then we setup a billing for this account - await provisionsStorage.put({ - // @ts-expect-error - provider: connection.id.did(), - account: alice.agent.did(), - consumer: space.did(), - }) - - const cid = await alice.capability.store.add(car) - assert.deepEqual(cid, car.cid) - - const result = await alice.capability.store.get(car.cid) - - assert.equal(result.link.toString(), car.cid.toString()) - assert.equal(result.size, car.size) - }, -}) - -Test.test({ StoreClient }) diff --git a/packages/w3up-client/test/capability/subscription.test.js b/packages/w3up-client/test/capability/subscription.test.js index c4d036712..82860a127 100644 --- a/packages/w3up-client/test/capability/subscription.test.js +++ b/packages/w3up-client/test/capability/subscription.test.js @@ -8,7 +8,9 @@ export const SubscriptionClient = Test.withContext({ assert, { client, connection, service, plansStorage, grantAccess, mail } ) => { - const space = await client.createSpace('test') + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) const email = 'alice@web.mail' const login = Account.login(client, email) const message = await mail.take() diff --git a/packages/w3up-client/test/capability/upload.test.js b/packages/w3up-client/test/capability/upload.test.js index 573221908..649d91ce0 100644 --- a/packages/w3up-client/test/capability/upload.test.js +++ b/packages/w3up-client/test/capability/upload.test.js @@ -9,7 +9,9 @@ export const UploadClient = Test.withContext({ ) => { const car = await randomCAR(128) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -38,7 +40,9 @@ export const UploadClient = Test.withContext({ ) => { const car = await randomCAR(128) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -77,7 +81,9 @@ export const UploadClient = Test.withContext({ ) => { const car = await randomCAR(128) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -109,7 +115,9 @@ export const UploadClient = Test.withContext({ ) => { const car = await randomCAR(128) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) diff --git a/packages/w3up-client/test/capability/usage.test.js b/packages/w3up-client/test/capability/usage.test.js index d24b76136..7cce930d3 100644 --- a/packages/w3up-client/test/capability/usage.test.js +++ b/packages/w3up-client/test/capability/usage.test.js @@ -1,8 +1,7 @@ -import { AgentData } from '@web3-storage/access/agent' +import { AgentData } from '@storacha/access/agent' import { Client } from '../../src/client.js' import * as Test from '../test.js' import { receiptsEndpoint } from '../helpers/utils.js' -import { randomCAR } from '../helpers/random.js' export const UsageClient = Test.withContext({ report: { @@ -10,6 +9,7 @@ export const UsageClient = Test.withContext({ assert, { connection, provisionsStorage } ) => { + // 1. Setup alice account const alice = new Client(await AgentData.create(), { // @ts-ignore serviceConf: { @@ -18,7 +18,9 @@ export const UsageClient = Test.withContext({ }, }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) @@ -60,7 +62,9 @@ export const UsageClient = Test.withContext({ }, }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) @@ -69,47 +73,6 @@ export const UsageClient = Test.withContext({ assert.deepEqual(report, {}) }, }, - record: { - 'should record egress': async ( - assert, - { connection, provisionsStorage } - ) => { - const alice = new Client(await AgentData.create(), { - // @ts-ignore - serviceConf: { - access: connection, - upload: connection, - }, - }) - - const space = await alice.createSpace('test') - const auth = await space.createAuthorization(alice) - await alice.addSpace(auth) - - // Then we setup a billing for this account - await provisionsStorage.put({ - // @ts-expect-error - provider: connection.id.did(), - account: alice.agent.did(), - consumer: space.did(), - }) - - const car = await randomCAR(128) - const resource = car.cid - await alice.capability.upload.add(car.roots[0], [resource]) - - const result = await alice.capability.upload.get(car.roots[0]) - assert.ok(result) - - const record = await alice.capability.usage.record(space.did(), { - resource: resource.link(), - bytes: car.size, - servedAt: new Date().toISOString(), - }) - - assert.ok(record) - }, - }, }) Test.test({ UsageClient }) diff --git a/packages/w3up-client/test/client.test.js b/packages/w3up-client/test/client.test.js index 10da152c4..0b1487639 100644 --- a/packages/w3up-client/test/client.test.js +++ b/packages/w3up-client/test/client.test.js @@ -1,32 +1,40 @@ import assert from 'assert' import { parseLink } from '@ucanto/server' +import * as Server from '@ucanto/server' import { Agent, AgentData, claimAccess, requestAccess, -} from '@web3-storage/access/agent' +} from '@storacha/access/agent' import { randomBytes, randomCAR } from './helpers/random.js' import { toCAR } from './helpers/car.js' import { File } from './helpers/shims.js' -import { Client } from '../src/client.js' +import { authorizeContentServe, Client } from '../src/client.js' import * as Test from './test.js' import { receiptsEndpoint } from './helpers/utils.js' import { Absentee } from '@ucanto/principal' import { DIDMailto } from '../src/capability/access.js' -import { confirmConfirmationUrl } from '../../upload-api/test/helpers/utils.js' +import * as Result from './helpers/result.js' +import { + alice, + confirmConfirmationUrl, + gateway, +} from '../../upload-api/test/helpers/utils.js' +import * as SpaceCapability from '@storacha/capabilities/space' +import { getConnection, getContentServeMockService } from './mocks/service.js' /** @type {Test.Suite} */ export const testClient = { uploadFile: Test.withContext({ 'should upload a file to the service': async ( assert, - { connection, provisionsStorage, uploadTable, allocationsStorage } + { connection, provisionsStorage, uploadTable, registry } ) => { const bytes = await randomBytes(128) const file = new Blob([bytes]) const expectedCar = await toCAR(bytes) - /** @type {import('@web3-storage/upload-client/types').CARLink|undefined} */ + /** @type {import('@storacha/upload-client/types').CARLink|undefined} */ let carCID const alice = new Client(await AgentData.create(), { @@ -35,9 +43,12 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('upload-test') + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -54,20 +65,13 @@ export const testClient = { onShardStored: (meta) => { carCID = meta.cid }, - receiptsEndpoint, }) assert.deepEqual(await uploadTable.exists(space.did(), dataCID), { ok: true, }) - assert.deepEqual( - await allocationsStorage.exists(space.did(), expectedCar.cid.multihash), - { - ok: true, - } - ) - + Result.try(await registry.find(space.did(), expectedCar.cid.multihash)) assert.equal(carCID?.toString(), expectedCar.cid.toString()) assert.equal(dataCID.toString(), expectedCar.roots[0].toString()) }, @@ -102,7 +106,7 @@ export const testClient = { (bytes, index) => new File([bytes], `${index}.txt`) ) - /** @type {import('@web3-storage/upload-client/types').CARLink|undefined} */ + /** @type {import('@storacha/upload-client/types').CARLink|undefined} */ let carCID const alice = new Client(await AgentData.create(), { @@ -111,9 +115,12 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('upload-dir-test') + const space = await alice.createSpace('upload-dir-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) @@ -131,7 +138,6 @@ export const testClient = { onShardStored: (meta) => { carCID = meta.cid }, - receiptsEndpoint, }) assert.deepEqual(await uploadTable.exists(space.did(), dataCID), { @@ -144,7 +150,7 @@ export const testClient = { uploadCar: Test.withContext({ 'uploads a CAR file to the service': async ( assert, - { connection, provisionsStorage, uploadTable, allocationsStorage } + { connection, provisionsStorage, uploadTable, registry } ) => { const car = await randomCAR(32) @@ -156,9 +162,12 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) - const space = await alice.createSpace('car-space') + const space = await alice.createSpace('car-space', { + skipGatewayAuthorization: true, + }) await alice.addSpace(await space.createAuthorization(alice)) await alice.setCurrentSpace(space.did()) @@ -174,7 +183,6 @@ export const testClient = { onShardStored: (meta) => { carCID = meta.cid }, - receiptsEndpoint, }) assert.deepEqual(await uploadTable.exists(space.did(), root), { @@ -185,12 +193,7 @@ export const testClient = { return assert.ok(carCID) } - assert.deepEqual( - await allocationsStorage.exists(space.did(), carCID.multihash), - { - ok: true, - } - ) + Result.try(await registry.find(space.did(), carCID.multihash)) }, }), getReceipt: Test.withContext({ @@ -220,7 +223,9 @@ export const testClient = { const current0 = alice.currentSpace() assert.equal(current0, undefined) - const space = await alice.createSpace('new-space') + const space = await alice.createSpace('new-space', { + skipGatewayAuthorization: true, + }) await alice.addSpace(await space.createAuthorization(alice)) await alice.setCurrentSpace(space.did()) @@ -234,7 +239,9 @@ export const testClient = { const alice = new Client(await AgentData.create()) const name = `space-${Date.now()}` - const space = await alice.createSpace(name) + const space = await alice.createSpace(name, { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) @@ -248,7 +255,9 @@ export const testClient = { const alice = new Client(await AgentData.create()) const bob = new Client(await AgentData.create()) - const space = await alice.createSpace('new-space') + const space = await alice.createSpace('new-space', { + skipGatewayAuthorization: true, + }) await alice.addSpace( await space.createAuthorization(alice, { access: { '*': {} }, @@ -283,6 +292,7 @@ export const testClient = { // Step 2: Alice creates a space with her account as the recovery account const space = await client.createSpace('recovery-space-test', { account: aliceAccount, // The account is the recovery account + skipGatewayAuthorization: true, }) assert.ok(space) @@ -314,7 +324,9 @@ export const testClient = { await aliceLogin // Step 2: Alice creates a space without providing a recovery account - const space = await client.createSpace('no-recovery-space-test') + const space = await client.createSpace('no-recovery-space-test', { + skipGatewayAuthorization: true, + }) assert.ok(space) // Step 3: Attempt to access the space from a new device @@ -417,6 +429,7 @@ export const testClient = { // Step 2: Alice creates a space const space = await aliceClient.createSpace('share-space-test', { account: aliceAccount, + skipGatewayAuthorization: true, }) assert.ok(space) @@ -469,6 +482,7 @@ export const testClient = { 'share-space-delegate-fail-test', { account: aliceAccount, + skipGatewayAuthorization: true, } ) assert.ok(space) @@ -505,12 +519,14 @@ export const testClient = { // Step 2: Alice creates a space const spaceA = await client.createSpace('test-space-a', { account: aliceAccount, + skipGatewayAuthorization: true, }) assert.ok(spaceA) // Step 3: Alice creates another space to share with a friend const spaceB = await client.createSpace('test-space-b', { account: aliceAccount, + skipGatewayAuthorization: true, }) assert.ok(spaceB) @@ -527,12 +543,201 @@ export const testClient = { ) }, }), + authorizeGateway: Test.withContext({ + 'should explicitly authorize a gateway to serve content from a space': + async (assert, { mail, grantAccess, connection }) => { + // Step 1: Create a client for Alice and login + const aliceClient = new Client( + await AgentData.create({ + principal: alice, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + const aliceEmail = 'alice@web.mail' + const aliceLogin = aliceClient.login(aliceEmail) + const message = await mail.take() + assert.deepEqual(message.to, aliceEmail) + await grantAccess(message) + const aliceAccount = await aliceLogin + + // Step 2: Alice creates a space + const spaceA = await aliceClient.createSpace( + 'authorize-gateway-space', + { + account: aliceAccount, + skipGatewayAuthorization: true, + } + ) + assert.ok(spaceA) + + const gatewayService = getContentServeMockService() + const gatewayConnection = getConnection( + gateway, + gatewayService + ).connection + + // Step 3: Alice authorizes the gateway to serve content from the space + const delegationResult = await authorizeContentServe( + aliceClient, + spaceA, + gatewayConnection + ) + assert.ok(delegationResult.ok) + const { delegation } = delegationResult.ok + + // Step 4: Find the delegation for the default gateway + assert.equal(delegation.audience.did(), gateway.did()) + assert.ok( + delegation.capabilities.some( + (c) => + c.can === SpaceCapability.contentServe.can && + c.with === spaceA.did() + ) + ) + }, + 'should automatically authorize a gateway to serve content from a space when the space is created': + async (assert, { mail, grantAccess, connection }) => { + // Step 1: Create a client for Alice and login + const aliceClient = new Client( + await AgentData.create({ + principal: alice, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + const aliceEmail = 'alice@web.mail' + const aliceLogin = aliceClient.login(aliceEmail) + const message = await mail.take() + assert.deepEqual(message.to, aliceEmail) + await grantAccess(message) + const aliceAccount = await aliceLogin + + // Step 2: Alice creates a space + const gatewayService = getContentServeMockService() + const gatewayConnection = getConnection( + gateway, + gatewayService + ).connection + + try { + const spaceA = await aliceClient.createSpace( + 'authorize-gateway-space', + { + account: aliceAccount, + authorizeGatewayServices: [gatewayConnection], + } + ) + assert.ok(spaceA, 'should create the space') + } catch (error) { + assert.fail(error, 'should not throw when creating the space') + } + }, + 'should authorize the Storacha Gateway Service when no Gateway Services are provided': + async (assert, { mail, grantAccess, connection }) => { + // Step 1: Create a client for Alice and login + const aliceClient = new Client( + await AgentData.create({ + principal: alice, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + const aliceEmail = 'alice@web.mail' + const aliceLogin = aliceClient.login(aliceEmail) + const message = await mail.take() + assert.deepEqual(message.to, aliceEmail) + await grantAccess(message) + const aliceAccount = await aliceLogin + + process.env.DEFAULT_GATEWAY_ID = gateway.did() + process.env.DEFAULT_GATEWAY_URL = 'http://localhost:5001' + + const spaceA = await aliceClient.createSpace( + 'authorize-gateway-space', + { + account: aliceAccount, + authorizeGatewayServices: [], // If no Gateway Services are provided, authorize the Storacha Gateway Service + } + ) + assert.ok(spaceA, 'should create the space') + }, + 'should throw when content serve service can not process the invocation': + async (assert, { mail, grantAccess, connection }) => { + // Step 1: Create a client for Alice and login + const aliceClient = new Client( + await AgentData.create({ + principal: alice, + }), + { + // @ts-ignore + serviceConf: { + access: connection, + upload: connection, + }, + } + ) + + const aliceEmail = 'alice@web.mail' + const aliceLogin = aliceClient.login(aliceEmail) + const message = await mail.take() + assert.deepEqual(message.to, aliceEmail) + await grantAccess(message) + const aliceAccount = await aliceLogin + + // Step 2: Alice creates a space + const gatewayService = getContentServeMockService({ + error: Server.fail( + 'Content serve service can not process the invocation' + ).error, + }) + const gatewayConnection = getConnection( + gateway, + gatewayService + ).connection + + try { + await aliceClient.createSpace('authorize-gateway-space', { + account: aliceAccount, + authorizeGatewayServices: [gatewayConnection], + }) + assert.fail('should not create the space') + } catch (error) { + assert.match( + // @ts-expect-error + error.message, + /failed to publish delegation for audience/, + 'should throw when publishing the delegation' + ) + } + }, + }), proofs: { 'should get proofs': async (assert) => { const alice = new Client(await AgentData.create()) const bob = new Client(await AgentData.create()) - const space = await alice.createSpace('proof-space') + const space = await alice.createSpace('proof-space', { + skipGatewayAuthorization: true, + }) await alice.addSpace(await space.createAuthorization(alice)) await alice.setCurrentSpace(space.did()) @@ -550,7 +755,9 @@ export const testClient = { const alice = new Client(await AgentData.create()) const bob = new Client(await AgentData.create()) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) await alice.addSpace(await space.createAuthorization(alice)) await alice.setCurrentSpace(space.did()) const name = `delegation-${Date.now()}` @@ -586,7 +793,9 @@ export const testClient = { }, }) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) await alice.addSpace( await space.createAuthorization(alice, { access: { '*': {} }, @@ -608,7 +817,9 @@ export const testClient = { const alice = new Client(await AgentData.create()) const bob = new Client(await AgentData.create()) - const space = await alice.createSpace('test') + const space = await alice.createSpace('test', { + skipGatewayAuthorization: true, + }) await alice.addSpace(await space.createAuthorization(alice)) await alice.setCurrentSpace(space.did()) const name = `delegation-${Date.now()}` @@ -623,7 +834,7 @@ export const testClient = { defaultProvider: { 'should return the connection ID': async (assert) => { const alice = new Client(await AgentData.create()) - assert.equal(alice.defaultProvider(), 'did:web:web3.storage') + assert.equal(alice.defaultProvider(), 'did:web:upload.storacha.network') }, }, @@ -655,10 +866,13 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) // setup space - const space = await alice.createSpace('upload-test') + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -672,9 +886,7 @@ export const testClient = { }) const content = new Blob([bytes]) - const fileLink = await alice.uploadFile(content, { - receiptsEndpoint, - }) + const fileLink = await alice.uploadFile(content) assert.deepEqual(await uploadTable.exists(space.did(), fileLink), { ok: true, @@ -705,10 +917,13 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) // setup space - const space = await alice.createSpace('upload-test') + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -722,9 +937,7 @@ export const testClient = { }) const content = new Blob([bytes]) - const fileLink = await alice.uploadFile(content, { - receiptsEndpoint, - }) + const fileLink = await alice.uploadFile(content) assert.deepEqual(await uploadTable.exists(space.did(), fileLink), { ok: true, @@ -762,7 +975,9 @@ export const testClient = { }) // setup space - const space = await alice.createSpace('upload-test') + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -782,10 +997,13 @@ export const testClient = { access: connection, upload: connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) // setup space - const space = await alice.createSpace('upload-test') + const space = await alice.createSpace('upload-test', { + skipGatewayAuthorization: true, + }) const auth = await space.createAuthorization(alice) await alice.addSpace(auth) await alice.setCurrentSpace(space.did()) @@ -799,9 +1017,7 @@ export const testClient = { }) const content = new Blob(bytesArray) - const fileLink = await alice.uploadFile(content, { - receiptsEndpoint, - }) + const fileLink = await alice.uploadFile(content) const upload = await uploadTable.get(space.did(), fileLink) diff --git a/packages/w3up-client/test/coupon.test.js b/packages/w3up-client/test/coupon.test.js index faee5f227..c5cefb70d 100644 --- a/packages/w3up-client/test/coupon.test.js +++ b/packages/w3up-client/test/coupon.test.js @@ -10,13 +10,16 @@ export const testCoupon = Test.withContext({ { client, mail, connect, grantAccess, plansStorage } ) => { // First we login to the workshop account - const login = client.login('workshop@web3.storage') + const login = client.login('workshop@storacha.network') const message = await mail.take() await grantAccess(message) const account = await login // Then we setup a billing for this account - await plansStorage.set(account.did(), 'did:web:test.web3.storage') + await plansStorage.set( + account.did(), + 'did:web:test.upload.storacha.network' + ) // Then we use the account to issue a coupon for the workshop const coupon = await client.coupon.issue({ @@ -37,7 +40,9 @@ export const testCoupon = Test.withContext({ const access = await alice.coupon.redeem(archive) // creates a space and provision it with redeemed coupon - const space = await alice.createSpace('home') + const space = await alice.createSpace('home', { + skipGatewayAuthorization: true, + }) const result = await space.provision(access) await space.save() @@ -45,7 +50,7 @@ export const testCoupon = Test.withContext({ const info = await alice.capability.space.info(space.did()) assert.deepEqual(info.did, space.did()) - assert.deepEqual(info.providers, ['did:web:test.web3.storage']) + assert.deepEqual(info.providers, ['did:web:test.upload.storacha.network']) }, 'coupon with password': async ( diff --git a/packages/w3up-client/test/helpers/bucket-server.js b/packages/w3up-client/test/helpers/bucket-server.js index 72120c013..671a311f6 100644 --- a/packages/w3up-client/test/helpers/bucket-server.js +++ b/packages/w3up-client/test/helpers/bucket-server.js @@ -11,6 +11,10 @@ const server = createServer(async (req, res) => { res.setHeader('Access-Control-Allow-Methods', '*') res.setHeader('Access-Control-Allow-Headers', '*') if (req.method === 'OPTIONS') return res.end() + if (req.method === 'POST' && req.url === '/reset') { + data.clear() + return res.end() + } res.statusCode = status if (status === 200) { diff --git a/packages/w3up-client/test/helpers/car.js b/packages/w3up-client/test/helpers/car.js index 5cae6a4d1..07aa974db 100644 --- a/packages/w3up-client/test/helpers/car.js +++ b/packages/w3up-client/test/helpers/car.js @@ -11,7 +11,6 @@ export async function toCAR(bytes) { const hash = await sha256.digest(bytes) const root = CID.create(1, raw.code, hash) - // @ts-expect-error old multiformats in @ipld/car const { writer, out } = CarWriter.create(root) writer.put({ cid: root, bytes }) writer.close() diff --git a/packages/w3up-client/test/helpers/filecoin.js b/packages/w3up-client/test/helpers/filecoin.js index c89a9f321..6e47e2007 100644 --- a/packages/w3up-client/test/helpers/filecoin.js +++ b/packages/w3up-client/test/helpers/filecoin.js @@ -1,4 +1,4 @@ -import * as StorefrontCapabilities from '@web3-storage/capabilities/filecoin/storefront' +import * as StorefrontCapabilities from '@storacha/capabilities/filecoin/storefront' import * as Server from '@ucanto/server' /** diff --git a/packages/w3up-client/test/helpers/gateway-server.js b/packages/w3up-client/test/helpers/gateway-server.js new file mode 100644 index 000000000..34dd7c814 --- /dev/null +++ b/packages/w3up-client/test/helpers/gateway-server.js @@ -0,0 +1,61 @@ +import { createServer } from 'node:http' +import { + createUcantoServer, + getContentServeMockService, +} from '../mocks/service.js' +import { gateway } from '../../../upload-api/test/helpers/utils.js' + +const port = 5001 + +const server = createServer(async (req, res) => { + res.setHeader('Access-Control-Allow-Origin', '*') + res.setHeader('Access-Control-Allow-Methods', '*') + res.setHeader('Access-Control-Allow-Headers', '*') + if (req.method === 'OPTIONS') return res.end() + + if (req.method === 'POST') { + const service = getContentServeMockService() + const server = createUcantoServer(gateway, service) + + const bodyBuffer = Buffer.concat(await collect(req)) + + const reqHeaders = /** @type {Record} */ ( + Object.fromEntries(Object.entries(req.headers)) + ) + + const { headers, body, status } = await server.request({ + body: new Uint8Array( + bodyBuffer.buffer, + bodyBuffer.byteOffset, + bodyBuffer.byteLength + ), + headers: reqHeaders, + }) + + for (const [key, value] of Object.entries(headers)) { + res.setHeader(key, value) + } + res.writeHead(status ?? 200) + res.end(body) + } + res.end() +}) + +/** @param {import('node:stream').Readable} stream */ +const collect = (stream) => { + return /** @type {Promise} */ ( + new Promise((resolve, reject) => { + const chunks = /** @type {Buffer[]} */ ([]) + stream.on('data', (chunk) => chunks.push(Buffer.from(chunk))) + stream.on('error', (err) => reject(err)) + stream.on('end', () => resolve(chunks)) + }) + ) +} + +// eslint-disable-next-line no-console +server.listen(port, () => + console.log(`[Mock] Gateway Server Listening on :${port}`) +) + +process.on('SIGTERM', () => process.exit(0)) diff --git a/packages/w3up-client/test/helpers/result.js b/packages/w3up-client/test/helpers/result.js new file mode 100644 index 000000000..1df360b81 --- /dev/null +++ b/packages/w3up-client/test/helpers/result.js @@ -0,0 +1,22 @@ +export * from '@ucanto/core/result' +import * as API from '@ucanto/interface' + +/** + * Returns contained `ok` if result is and throws `error` if result is not ok. + * + * @template T + * @param {API.Result} result + * @returns {T} + */ +export const unwrap = ({ ok, error }) => { + if (error) { + throw error + } else { + return /** @type {T} */ (ok) + } +} + +/** + * Also expose as `Result.try` which is arguably more clear. + */ +export { unwrap as try } diff --git a/packages/w3up-client/test/helpers/utils.js b/packages/w3up-client/test/helpers/utils.js index a14f2f133..8e53c35aa 100644 --- a/packages/w3up-client/test/helpers/utils.js +++ b/packages/w3up-client/test/helpers/utils.js @@ -1,10 +1,10 @@ -import { conclude } from '@web3-storage/capabilities/ucan' +import { conclude } from '@storacha/capabilities/ucan' import { Receipt } from '@ucanto/core' import * as Server from '@ucanto/server' -import { UCAN } from '@web3-storage/capabilities' -import * as HTTP from '@web3-storage/capabilities/http' -import * as W3sBlobCapabilities from '@web3-storage/capabilities/web3.storage/blob' -import { W3sBlob } from '@web3-storage/capabilities' +import { UCAN } from '@storacha/capabilities' +import * as HTTP from '@storacha/capabilities/http' +import * as W3sBlobCapabilities from '@storacha/capabilities/web3.storage/blob' +import { W3sBlob } from '@storacha/capabilities' import * as Types from '../../src/types.js' export const validateAuthorization = () => ({ ok: {} }) diff --git a/packages/w3up-client/test/index.node.test.js b/packages/w3up-client/test/index.node.test.js index a32372946..c1e3d99f7 100644 --- a/packages/w3up-client/test/index.node.test.js +++ b/packages/w3up-client/test/index.node.test.js @@ -1,7 +1,7 @@ import * as Test from './test.js' import { Signer } from '@ucanto/principal/ed25519' import { EdDSA } from '@ipld/dag-ucan/signature' -import { StoreConf } from '@web3-storage/access/stores/store-conf' +import { StoreConf } from '@storacha/access/stores/store-conf' import { create } from '../src/index.node.js' /** diff --git a/packages/w3up-client/test/legacy-compat.node.test.js b/packages/w3up-client/test/legacy-compat.node.test.js new file mode 100644 index 000000000..43a4851e8 --- /dev/null +++ b/packages/w3up-client/test/legacy-compat.node.test.js @@ -0,0 +1,69 @@ +import http from 'node:http' +import { Client } from '@web3-storage/w3up-client' +import { AgentData } from '@web3-storage/access' +import * as Link from 'multiformats/link' +import { Message } from '@ucanto/core' +import * as CAR from '@ucanto/transport/car' +import * as Test from './test.js' +import { randomBytes } from './helpers/random.js' + +/** @param {import('@storacha/upload-api').AgentStore} agentStore */ +const createReceiptsServer = (agentStore) => + http.createServer(async (req, res) => { + const task = Link.parse(req.url?.split('/').pop() ?? '') + const receiptGet = await agentStore.receipts.get(task) + if (receiptGet.error) { + res.writeHead(404) + return res.end() + } + const message = await Message.build({ receipts: [receiptGet.ok] }) + const request = CAR.request.encode(message) + res.writeHead(200) + res.end(request.body) + }) + +/** @type {Test.Suite} */ +export const testLegacyCompatibility = { + uploadFile: Test.withContext({ + 'should upload a file to the service via legacy client': async ( + assert, + { connection, provisionsStorage, agentStore } + ) => { + const receiptsServer = createReceiptsServer(agentStore) + const receiptsEndpoint = await new Promise((resolve) => { + receiptsServer.listen(() => { + // @ts-expect-error + resolve(new URL(`http://127.0.0.1:${receiptsServer.address().port}`)) + }) + }) + + try { + const bytes = await randomBytes(128) + const file = new Blob([bytes]) + const alice = new Client(await AgentData.create(), { + // @ts-expect-error service no longer implements `store/*` + serviceConf: { access: connection, upload: connection }, + receiptsEndpoint, + }) + + const space = await alice.createSpace('upload-test') + const auth = await space.createAuthorization(alice) + await alice.addSpace(auth) + await alice.setCurrentSpace(space.did()) + + await provisionsStorage.put({ + // @ts-expect-error + provider: connection.id.did(), + account: alice.agent.did(), + consumer: space.did(), + }) + + await assert.doesNotReject(alice.uploadFile(file)) + } finally { + receiptsServer.close() + } + }, + }), +} + +Test.test({ LegacyCompatibility: testLegacyCompatibility }) diff --git a/packages/w3up-client/test/mocks/service.js b/packages/w3up-client/test/mocks/service.js new file mode 100644 index 000000000..b2a4cfe4e --- /dev/null +++ b/packages/w3up-client/test/mocks/service.js @@ -0,0 +1,53 @@ +import * as Client from '@ucanto/client' +import * as Server from '@ucanto/server' +import { HTTP } from '@ucanto/transport' +import * as CAR from '@ucanto/transport/car' +import * as AccessCaps from '@storacha/capabilities' + +/** + * Mocked Gateway/Content Serve service + * + * @param {{ ok: any } | { error: Server.API.Failure }} result + */ +export function getContentServeMockService(result = { ok: {} }) { + return { + access: { + delegate: Server.provide(AccessCaps.Access.delegate, async () => { + return result + }), + }, + } +} + +/** + * Creates a new Ucanto server with the given options. + * + * @param {any} id + * @param {any} service + */ +export function createUcantoServer(id, service) { + return Server.create({ + id: id, + service, + codec: CAR.inbound, + validateAuthorization: () => ({ ok: {} }), + }) +} + +/** + * Generic function to create connection to any type of mock service with any type of signer id. + * + * @param {any} id + * @param {any} service + * @param {string | undefined} [url] + */ +export function getConnection(id, service, url = undefined) { + const server = createUcantoServer(id, service) + const connection = Client.connect({ + id: id, + codec: CAR.outbound, + channel: url ? HTTP.open({ url: new URL(url) }) : server, + }) + + return { connection } +} diff --git a/packages/w3up-client/test/space.test.js b/packages/w3up-client/test/space.test.js index a6a0d1281..5937fdf9b 100644 --- a/packages/w3up-client/test/space.test.js +++ b/packages/w3up-client/test/space.test.js @@ -1,10 +1,10 @@ import * as Signer from '@ucanto/principal/ed25519' -import * as StoreCapabilities from '@web3-storage/capabilities/store' import * as Test from './test.js' import { Space } from '../src/space.js' import * as Account from '../src/account.js' import * as Result from '../src/result.js' import { randomCAR } from './helpers/random.js' +import { receiptsEndpoint } from './helpers/utils.js' /** * @type {Test.Suite} @@ -24,7 +24,9 @@ export const testSpace = Test.withContext({ }, 'should get usage': async (assert, { client, grantAccess, mail }) => { - const space = await client.createSpace('test') + const space = await client.createSpace('test', { + skipGatewayAuthorization: true, + }) const email = 'alice@web.mail' const login = Account.login(client, email) @@ -38,11 +40,8 @@ export const testSpace = Test.withContext({ const size = 1138 const archive = await randomCAR(size) - await client.agent.invokeAndExecute(StoreCapabilities.add, { - nb: { - link: archive.cid, - size, - }, + await client.capability.blob.add(new Blob([archive.bytes]), { + receiptsEndpoint, }) const found = client.spaces().find((s) => s.did() === space.did()) diff --git a/packages/w3up-client/test/test.js b/packages/w3up-client/test/test.js index fd0647944..d1ae28aa5 100644 --- a/packages/w3up-client/test/test.js +++ b/packages/w3up-client/test/test.js @@ -1,7 +1,8 @@ -import { StoreMemory } from '@web3-storage/access/stores/store-memory' -import * as Context from '@web3-storage/upload-api/test/context' -import * as Client from '@web3-storage/w3up-client' +import { StoreMemory } from '@storacha/access/stores/store-memory' +import * as Context from '@storacha/upload-api/test/context' +import * as Client from '@storacha/client' import * as assert from 'assert' +import { receiptsEndpoint } from './helpers/utils.js' /** * @template [Context=void] @@ -83,6 +84,7 @@ export const setup = async () => { upload: context.connection, filecoin: context.connection, }, + receiptsEndpoint: new URL(receiptsEndpoint), }) return { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5597e455..6389cb7a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,17 +13,17 @@ importers: version: 1.4.7 typedoc-plugin-missing-exports: specifier: ^2.1.0 - version: 2.2.0(typedoc@0.25.13(typescript@5.2.2)) + version: 2.3.0(typedoc@0.25.13(typescript@5.2.2)) devDependencies: '@arethetypeswrong/cli': specifier: ^0.15.3 - version: 0.15.3 + version: 0.15.4 '@docusaurus/core': specifier: ^3.0.0 - version: 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + version: 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) '@docusaurus/preset-classic': specifier: ^3.0.0 - version: 3.3.2(@algolia/client-search@4.23.3)(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0)(typescript@5.2.2) + version: 3.7.0(@algolia/client-search@5.20.0)(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.2.2) docusaurus-plugin-typedoc: specifier: ^0.21.0 version: 0.21.0(typedoc-plugin-markdown@3.17.1(typedoc@0.25.13(typescript@5.2.2)))(typedoc@0.25.13(typescript@5.2.2)) @@ -50,13 +50,19 @@ importers: dependencies: '@ipld/car': specifier: ^5.1.1 - version: 5.3.0 + version: 5.4.0 '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 + specifier: ^3.4.5 + version: 3.4.5 '@scure/bip39': specifier: ^1.2.1 - version: 1.3.0 + version: 1.5.4 + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities + '@storacha/did-mailto': + specifier: workspace:^ + version: link:../did-mailto '@storacha/one-webcrypto': specifier: ^1.0.1 version: 1.0.1 @@ -64,26 +70,20 @@ importers: specifier: ^9.0.1 version: 9.0.1 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 '@ucanto/validator': - specifier: ^9.0.2 - version: 9.0.2 - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities - '@web3-storage/did-mailto': - specifier: workspace:^ - version: link:../did-mailto + specifier: ^9.0.3 + version: 9.0.3 bigint-mod-arith: specifier: ^3.1.2 version: 3.3.1 @@ -91,30 +91,33 @@ importers: specifier: 11.0.2 version: 11.0.2 multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 p-defer: specifier: ^4.0.0 version: 4.0.1 type-fest: specifier: ^4.9.0 - version: 4.18.2 + version: 4.33.0 uint8arrays: - specifier: ^4.0.6 - version: 4.0.10 + specifier: ^5.1.0 + version: 5.1.0 devDependencies: + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/inquirer': specifier: ^9.0.4 version: 9.0.7 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@types/node': specifier: ^20.8.4 - version: 20.12.10 + version: 20.17.14 '@types/sinon': specifier: ^10.0.19 version: 10.0.20 @@ -123,19 +126,16 @@ importers: version: 6.0.3 '@types/ws': specifier: ^8.5.4 - version: 8.5.10 + version: 8.5.13 '@ucanto/server': - specifier: ^10.0.0 - version: 10.0.0 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up + specifier: ^10.1.0 + version: 10.1.0 assert: specifier: ^2.0.0 version: 2.1.0 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 playwright-test: specifier: ^12.3.4 version: 12.6.1 @@ -153,41 +153,41 @@ importers: dependencies: '@ipld/dag-cbor': specifier: ^9.0.6 - version: 9.2.0 + version: 9.2.2 + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities '@storacha/one-webcrypto': specifier: ^1.0.1 version: 1.0.1 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities + specifier: ^10.1.1 + version: 10.1.1 carstream: specifier: ^2.1.0 - version: 2.1.0 + version: 2.3.0 multiformats: specifier: ^13.0.1 - version: 13.1.0 + version: 13.3.1 uint8arrays: specifier: ^5.0.3 - version: 5.0.3 + version: 5.1.0 devDependencies: + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up c8: specifier: ^7.14.0 version: 7.14.0 entail: specifier: ^2.1.2 - version: 2.1.2 + version: 2.2.1 typescript: specifier: 5.2.2 version: 5.2.2 @@ -195,45 +195,48 @@ importers: packages/capabilities: dependencies: '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 '@ucanto/validator': - specifier: ^9.0.2 - version: 9.0.2 + specifier: ^9.0.3 + version: 9.0.3 '@web3-storage/data-segment': specifier: ^5.2.0 - version: 5.2.0 + version: 5.3.0 uint8arrays: specifier: ^5.0.3 - version: 5.0.3 + version: 5.1.0 devDependencies: + '@ipld/dag-ucan': + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.0 - version: 10.0.6 + version: 10.0.10 '@types/node': specifier: ^20.8.4 - version: 20.12.10 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up + version: 20.17.14 assert: specifier: ^2.0.0 version: 2.1.0 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 playwright-test: specifier: ^12.3.4 version: 12.6.1 @@ -247,20 +250,138 @@ importers: specifier: ^1.0.2 version: 1.0.2 + packages/cli: + dependencies: + '@inquirer/core': + specifier: ^5.1.1 + version: 5.1.2 + '@inquirer/prompts': + specifier: ^3.3.0 + version: 3.3.2 + '@ipld/car': + specifier: ^5.2.4 + version: 5.4.0 + '@ipld/dag-json': + specifier: ^10.1.5 + version: 10.2.3 + '@ipld/dag-ucan': + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/access': + specifier: workspace:^ + version: link:../access-client + '@storacha/client': + specifier: workspace:^ + version: link:../w3up-client + '@storacha/did-mailto': + specifier: workspace:^ + version: link:../did-mailto + '@ucanto/client': + specifier: ^9.0.1 + version: 9.0.1 + '@ucanto/core': + specifier: ^10.2.1 + version: 10.2.1 + '@ucanto/transport': + specifier: ^9.1.1 + version: 9.1.1 + '@web3-storage/content-claims': + specifier: ^5.1.3 + version: 5.1.3 + '@web3-storage/data-segment': + specifier: ^5.0.0 + version: 5.3.0 + ansi-escapes: + specifier: ^6.2.0 + version: 6.2.1 + chalk: + specifier: ^5.3.0 + version: 5.4.1 + crypto-random-string: + specifier: ^5.0.0 + version: 5.0.0 + files-from-path: + specifier: ^1.0.4 + version: 1.1.1 + fr32-sha2-256-trunc254-padded-binary-tree-multihash: + specifier: ^3.3.0 + version: 3.3.0 + open: + specifier: ^9.1.0 + version: 9.1.0 + ora: + specifier: ^7.0.1 + version: 7.0.1 + pretty-tree: + specifier: ^1.0.0 + version: 1.0.0 + s-ago: + specifier: ^2.2.0 + version: 2.2.0 + sade: + specifier: ^1.8.1 + version: 1.8.1 + update-notifier: + specifier: ^7.0.0 + version: 7.3.1 + devDependencies: + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up + '@storacha/upload-api': + specifier: workspace:^ + version: link:../upload-api + '@types/update-notifier': + specifier: ^6.0.5 + version: 6.0.8 + '@ucanto/interface': + specifier: ^10.1.1 + version: 10.1.1 + '@ucanto/principal': + specifier: ^9.0.2 + version: 9.0.2 + '@ucanto/server': + specifier: ^10.1.0 + version: 10.1.0 + '@web-std/blob': + specifier: ^3.0.5 + version: 3.0.5 + '@web3-storage/sigv4': + specifier: ^1.0.2 + version: 1.0.2 + entail: + specifier: ^2.1.1 + version: 2.2.1 + multiformats: + specifier: ^13.1.1 + version: 13.3.1 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + prettier: + specifier: ^3.0.3 + version: 3.4.2 + typescript: + specifier: ^5.2.2 + version: 5.2.2 + packages/did-mailto: devDependencies: + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up + version: 10.0.10 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 typescript: specifier: 5.2.2 version: 5.2.2 @@ -269,46 +390,46 @@ importers: dependencies: '@typescript-eslint/eslint-plugin': specifier: ^6.9.1 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3) '@typescript-eslint/parser': specifier: ^6.9.1 - version: 6.21.0(eslint@8.57.0)(typescript@5.3.3) + version: 6.21.0(eslint@8.57.1)(typescript@5.3.3) eslint: specifier: ^8.56.0 - version: 8.57.0 + version: 8.57.1 eslint-plugin-jsdoc: specifier: ^46.8.2 - version: 46.10.1(eslint@8.57.0) + version: 46.10.1(eslint@8.57.1) packages/filecoin-api: dependencies: '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities '@ucanto/client': specifier: ^9.0.1 version: 9.0.1 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/server': - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.1.0 + version: 10.1.0 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities '@web3-storage/content-claims': specifier: ^5.0.0 - version: 5.0.0 + version: 5.1.3 '@web3-storage/data-segment': specifier: ^5.2.0 - version: 5.2.0 + version: 5.3.0 fr32-sha2-256-trunc254-padded-binary-tree-multihash: specifier: ^3.3.0 version: 3.3.0 @@ -316,36 +437,36 @@ importers: specifier: ^6.0.0 version: 6.0.0 devDependencies: + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up + '@storacha/filecoin-client': + specifier: workspace:^ + version: link:../filecoin-client '@storacha/one-webcrypto': specifier: ^1.0.1 version: 1.0.1 '@types/assert': specifier: ^1.5.10 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@web-std/blob': specifier: ^3.0.5 version: 3.0.5 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up - '@web3-storage/filecoin-client': - specifier: workspace:^ - version: link:../filecoin-client c8: specifier: ^10.1.2 - version: 10.1.2 + version: 10.1.3 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 p-wait-for: specifier: ^5.0.2 version: 5.0.2 @@ -356,45 +477,45 @@ importers: packages/filecoin-client: dependencies: '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities '@ucanto/client': specifier: ^9.0.1 version: 9.0.1 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities devDependencies: '@ipld/dag-json': specifier: ^10.1.4 - version: 10.2.0 + version: 10.2.3 + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@ucanto/server': - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.1.0 + version: 10.1.0 '@web3-storage/data-segment': - specifier: ^4.0.0 - version: 4.0.0 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up + specifier: ^5.3.0 + version: 5.3.0 assert: specifier: ^2.0.0 version: 2.1.0 @@ -406,10 +527,10 @@ importers: version: 0.0.9 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -422,79 +543,79 @@ importers: packages/upload-api: dependencies: + '@storacha/access': + specifier: workspace:^ + version: link:../access-client + '@storacha/blob-index': + specifier: workspace:^ + version: link:../blob-index + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities + '@storacha/did-mailto': + specifier: workspace:^ + version: link:../did-mailto + '@storacha/filecoin-api': + specifier: workspace:^ + version: link:../filecoin-api '@ucanto/client': specifier: ^9.0.1 version: 9.0.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@ucanto/server': specifier: ^10.0.0 - version: 10.0.0 + version: 10.1.0 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 '@ucanto/validator': - specifier: ^9.0.2 - version: 9.0.2 - '@web3-storage/access': - specifier: workspace:^ - version: link:../access-client - '@web3-storage/blob-index': - specifier: workspace:^ - version: link:../blob-index - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities + specifier: ^9.0.3 + version: 9.0.3 '@web3-storage/content-claims': - specifier: ^5.1.0 - version: 5.1.0 - '@web3-storage/did-mailto': - specifier: workspace:^ - version: link:../did-mailto - '@web3-storage/filecoin-api': - specifier: workspace:^ - version: link:../filecoin-api + specifier: ^5.1.3 + version: 5.1.3 + '@web3-storage/upload-api': + specifier: ^19.0.0 + version: 19.0.0 multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 uint8arrays: specifier: ^5.0.3 - version: 5.0.3 + version: 5.1.0 devDependencies: '@ipld/car': specifier: ^5.1.1 - version: 5.3.0 + version: 5.4.0 '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@storacha/one-webcrypto': specifier: ^1.0.1 version: 1.0.1 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@web-std/blob': specifier: ^3.0.5 version: 3.0.5 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up - '@web3-storage/sigv4': - specifier: ^1.0.2 - version: 1.0.2 is-subset: specifier: ^0.1.1 version: 0.1.1 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 typescript: specifier: 5.2.2 version: 5.2.2 @@ -503,46 +624,46 @@ importers: dependencies: '@ipld/car': specifier: ^5.2.2 - version: 5.3.0 + version: 5.4.0 '@ipld/dag-cbor': specifier: ^9.0.6 - version: 9.2.0 + version: 9.2.2 '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 + specifier: ^3.4.5 + version: 3.4.5 '@ipld/unixfs': - specifier: ^2.1.1 - version: 2.2.0 + specifier: ^3.0.0 + version: 3.0.0 + '@storacha/blob-index': + specifier: workspace:^ + version: link:../blob-index + '@storacha/capabilities': + specifier: workspace:^ + version: link:../capabilities + '@storacha/filecoin-client': + specifier: workspace:^ + version: link:../filecoin-client '@ucanto/client': specifier: ^9.0.1 version: 9.0.1 '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.2.1 + version: 10.2.1 '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^10.1.1 + version: 10.1.1 '@ucanto/transport': specifier: ^9.1.1 version: 9.1.1 - '@web3-storage/blob-index': - specifier: workspace:^ - version: link:../blob-index - '@web3-storage/capabilities': - specifier: workspace:^ - version: link:../capabilities '@web3-storage/data-segment': specifier: ^5.1.0 - version: 5.1.0 - '@web3-storage/filecoin-client': - specifier: workspace:^ - version: link:../filecoin-client + version: 5.3.0 ipfs-utils: specifier: ^9.0.14 version: 9.0.14(encoding@0.1.13) multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 p-retry: specifier: ^5.1.2 version: 5.1.2 @@ -550,27 +671,27 @@ importers: specifier: ^6.0.0 version: 6.0.0 devDependencies: + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@types/varint': specifier: ^6.0.1 version: 6.0.3 '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^9.0.2 + version: 9.0.2 '@ucanto/server': - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.1.0 + version: 10.1.0 '@web3-storage/content-claims': - specifier: ^5.0.0 - version: 5.0.0 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up + specifier: ^5.1.3 + version: 5.1.3 assert: specifier: ^2.0.0 version: 2.1.0 @@ -588,7 +709,7 @@ importers: version: 10.0.1 mocha: specifier: ^10.2.0 - version: 10.4.0 + version: 10.8.2 npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -602,87 +723,96 @@ importers: packages/w3up-client: dependencies: '@ipld/dag-ucan': - specifier: ^3.4.0 - version: 3.4.0 - '@ucanto/client': - specifier: ^9.0.1 - version: 9.0.1 - '@ucanto/core': - specifier: ^10.0.1 - version: 10.0.1 - '@ucanto/interface': - specifier: ^10.0.1 - version: 10.0.1 - '@ucanto/principal': - specifier: ^9.0.1 - version: 9.0.1 - '@ucanto/transport': - specifier: ^9.1.1 - version: 9.1.1 - '@web3-storage/access': + specifier: ^3.4.5 + version: 3.4.5 + '@storacha/access': specifier: workspace:^ version: link:../access-client - '@web3-storage/blob-index': + '@storacha/blob-index': specifier: workspace:^ version: link:../blob-index - '@web3-storage/capabilities': + '@storacha/capabilities': specifier: workspace:^ version: link:../capabilities - '@web3-storage/did-mailto': + '@storacha/did-mailto': specifier: workspace:^ version: link:../did-mailto - '@web3-storage/filecoin-client': + '@storacha/filecoin-client': specifier: workspace:^ version: link:../filecoin-client - '@web3-storage/upload-client': + '@storacha/upload-client': specifier: workspace:^ version: link:../upload-client + '@ucanto/client': + specifier: ^9.0.1 + version: 9.0.1 + '@ucanto/core': + specifier: ^10.2.1 + version: 10.2.1 + '@ucanto/interface': + specifier: ^10.1.1 + version: 10.1.1 + '@ucanto/principal': + specifier: ^9.0.2 + version: 9.0.2 + '@ucanto/transport': + specifier: ^9.1.1 + version: 9.1.1 devDependencies: '@ipld/car': specifier: ^5.1.1 - version: 5.3.0 + version: 5.4.0 '@ipld/unixfs': - specifier: ^2.1.1 - version: 2.2.0 + specifier: ^3.0.0 + version: 3.0.0 + '@storacha/eslint-config': + specifier: workspace:^ + version: link:../eslint-config-w3up + '@storacha/upload-api': + specifier: workspace:^ + version: link:../upload-api '@types/assert': specifier: ^1.5.6 - version: 1.5.10 + version: 1.5.11 '@types/mocha': specifier: ^10.0.1 - version: 10.0.6 + version: 10.0.10 '@types/node': specifier: ^20.8.4 - version: 20.12.10 + version: 20.17.14 '@ucanto/server': - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.1.0 + version: 10.1.0 + '@web3-storage/access': + specifier: ^20.1.0 + version: 20.1.1 '@web3-storage/content-claims': specifier: ^4.0.4 version: 4.0.5 '@web3-storage/data-segment': specifier: ^5.0.0 - version: 5.1.0 - '@web3-storage/eslint-config-w3up': - specifier: workspace:^ - version: link:../eslint-config-w3up - '@web3-storage/upload-api': - specifier: workspace:^ - version: link:../upload-api + version: 5.3.0 + '@web3-storage/w3up-client': + specifier: ^16.5.1 + version: 16.5.2 assert: specifier: ^2.0.0 version: 2.1.0 c8: specifier: ^7.13.0 version: 7.14.0 + esbuild: + specifier: ^0.24.0 + version: 0.24.2 hundreds: specifier: ^0.0.9 version: 0.0.9 mocha: - specifier: ^10.1.0 - version: 10.4.0 + specifier: ^10.8.2 + version: 10.8.2 multiformats: - specifier: ^12.1.2 - version: 12.1.3 + specifier: ^13.3.1 + version: 13.3.1 npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -693,78 +823,85 @@ importers: specifier: ^0.25.3 version: 0.25.13(typescript@5.2.2) typescript: - specifier: ^5.2.2 + specifier: 5.2.2 version: 5.2.2 packages: - '@algolia/autocomplete-core@1.9.3': - resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + '@algolia/autocomplete-core@1.17.9': + resolution: {integrity: sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==} - '@algolia/autocomplete-plugin-algolia-insights@1.9.3': - resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + '@algolia/autocomplete-plugin-algolia-insights@1.17.9': + resolution: {integrity: sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==} peerDependencies: search-insights: '>= 1 < 3' - '@algolia/autocomplete-preset-algolia@1.9.3': - resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + '@algolia/autocomplete-preset-algolia@1.17.9': + resolution: {integrity: sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-shared@1.9.3': - resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + '@algolia/autocomplete-shared@1.17.9': + resolution: {integrity: sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/cache-browser-local-storage@4.23.3': - resolution: {integrity: sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==} - - '@algolia/cache-common@4.23.3': - resolution: {integrity: sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==} + '@algolia/client-abtesting@5.20.0': + resolution: {integrity: sha512-YaEoNc1Xf2Yk6oCfXXkZ4+dIPLulCx8Ivqj0OsdkHWnsI3aOJChY5qsfyHhDBNSOhqn2ilgHWxSfyZrjxBcAww==} + engines: {node: '>= 14.0.0'} - '@algolia/cache-in-memory@4.23.3': - resolution: {integrity: sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==} + '@algolia/client-analytics@5.20.0': + resolution: {integrity: sha512-CIT9ni0+5sYwqehw+t5cesjho3ugKQjPVy/iPiJvtJX4g8Cdb6je6SPt2uX72cf2ISiXCAX9U3cY0nN0efnRDw==} + engines: {node: '>= 14.0.0'} - '@algolia/client-account@4.23.3': - resolution: {integrity: sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==} + '@algolia/client-common@5.20.0': + resolution: {integrity: sha512-iSTFT3IU8KNpbAHcBUJw2HUrPnMXeXLyGajmCL7gIzWOsYM4GabZDHXOFx93WGiXMti1dymz8k8R+bfHv1YZmA==} + engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@4.23.3': - resolution: {integrity: sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==} + '@algolia/client-insights@5.20.0': + resolution: {integrity: sha512-w9RIojD45z1csvW1vZmAko82fqE/Dm+Ovsy2ElTsjFDB0HMAiLh2FO86hMHbEXDPz6GhHKgGNmBRiRP8dDPgJg==} + engines: {node: '>= 14.0.0'} - '@algolia/client-common@4.23.3': - resolution: {integrity: sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==} + '@algolia/client-personalization@5.20.0': + resolution: {integrity: sha512-p/hftHhrbiHaEcxubYOzqVV4gUqYWLpTwK+nl2xN3eTrSW9SNuFlAvUBFqPXSVBqc6J5XL9dNKn3y8OA1KElSQ==} + engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@4.23.3': - resolution: {integrity: sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==} + '@algolia/client-query-suggestions@5.20.0': + resolution: {integrity: sha512-m4aAuis5vZi7P4gTfiEs6YPrk/9hNTESj3gEmGFgfJw3hO2ubdS4jSId1URd6dGdt0ax2QuapXufcrN58hPUcw==} + engines: {node: '>= 14.0.0'} - '@algolia/client-search@4.23.3': - resolution: {integrity: sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==} + '@algolia/client-search@5.20.0': + resolution: {integrity: sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==} + engines: {node: '>= 14.0.0'} '@algolia/events@4.0.1': resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - '@algolia/logger-common@4.23.3': - resolution: {integrity: sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==} - - '@algolia/logger-console@4.23.3': - resolution: {integrity: sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==} + '@algolia/ingestion@1.20.0': + resolution: {integrity: sha512-shj2lTdzl9un4XJblrgqg54DoK6JeKFO8K8qInMu4XhE2JuB8De6PUuXAQwiRigZupbI0xq8aM0LKdc9+qiLQA==} + engines: {node: '>= 14.0.0'} - '@algolia/recommend@4.23.3': - resolution: {integrity: sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==} + '@algolia/monitoring@1.20.0': + resolution: {integrity: sha512-aF9blPwOhKtWvkjyyXh9P5peqmhCA1XxLBRgItT+K6pbT0q4hBDQrCid+pQZJYy4HFUKjB/NDDwyzFhj/rwKhw==} + engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@4.23.3': - resolution: {integrity: sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==} + '@algolia/recommend@5.20.0': + resolution: {integrity: sha512-T6B/WPdZR3b89/F9Vvk6QCbt/wrLAtrGoL8z4qPXDFApQ8MuTFWbleN/4rHn6APWO3ps+BUePIEbue2rY5MlRw==} + engines: {node: '>= 14.0.0'} - '@algolia/requester-common@4.23.3': - resolution: {integrity: sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==} + '@algolia/requester-browser-xhr@5.20.0': + resolution: {integrity: sha512-t6//lXsq8E85JMenHrI6mhViipUT5riNhEfCcvtRsTV+KIBpC6Od18eK864dmBhoc5MubM0f+sGpKOqJIlBSCg==} + engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@4.23.3': - resolution: {integrity: sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==} + '@algolia/requester-fetch@5.20.0': + resolution: {integrity: sha512-FHxYGqRY+6bgjKsK4aUsTAg6xMs2S21elPe4Y50GB0Y041ihvw41Vlwy2QS6K9ldoftX4JvXodbKTcmuQxywdQ==} + engines: {node: '>= 14.0.0'} - '@algolia/transporter@4.23.3': - resolution: {integrity: sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==} + '@algolia/requester-node-http@5.20.0': + resolution: {integrity: sha512-kmtQClq/w3vtPteDSPvaW9SPZL/xrIgMrxZyAgsFwrJk0vJxqyC5/hwHmrCraDnStnGSADnLpBf4SpZnwnkwWw==} + engines: {node: '>= 14.0.0'} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} @@ -773,8 +910,8 @@ packages: '@andrewbranch/untar.js@1.0.3': resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} - '@arethetypeswrong/cli@0.15.3': - resolution: {integrity: sha512-sIMA9ZJBWDEg1+xt5RkAEflZuf8+PO8SdKj17x6PtETuUho+qlZJg4DgmKc3q+QwQ9zOB5VLK6jVRbFdNLdUIA==} + '@arethetypeswrong/cli@0.15.4': + resolution: {integrity: sha512-YDbImAi1MGkouT7f2yAECpUMFhhA1J0EaXzIqoC5GGtK0xDgauLtcsZezm8tNq7d3wOFXH7OnY+IORYcG212rw==} engines: {node: '>=18'} hasBin: true @@ -786,266 +923,171 @@ packages: resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==} engines: {node: '>=4'} - '@babel/code-frame@7.24.2': - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.24.4': - resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + '@babel/compat-data@7.26.5': + resolution: {integrity: sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==} engines: {node: '>=6.9.0'} - '@babel/core@7.24.5': - resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.24.5': - resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} + '@babel/generator@7.26.5': + resolution: {integrity: sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': - resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.24.5': - resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==} + '@babel/helper-create-class-features-plugin@7.25.9': + resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.22.15': - resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + '@babel/helper-create-regexp-features-plugin@7.26.3': + resolution: {integrity: sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.2': - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + '@babel/helper-define-polyfill-provider@0.6.3': + resolution: {integrity: sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + '@babel/helper-member-expression-to-functions@7.25.9': + resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.24.5': - resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.3': - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.24.5': - resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + '@babel/helper-optimise-call-expression@7.25.9': + resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.24.5': - resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.22.20': - resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + '@babel/helper-remap-async-to-generator@7.25.9': + resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.24.1': - resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + '@babel/helper-replace-supers@7.26.5': + resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.24.5': - resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.24.5': - resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.1': - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.5': - resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + '@babel/helper-wrap-function@7.25.9': + resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.24.5': - resolution: {integrity: sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.24.5': - resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.24.5': - resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.24.5': - resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + '@babel/parser@7.26.5': + resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.5': - resolution: {integrity: sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1': - resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1': - resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1': - resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-assertions@7.24.1': - resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.24.1': - resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 + hasBin: true - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': + resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-jsx@7.24.1': - resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9': + resolution: {integrity: sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': + resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': + resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.13.0 - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9': + resolution: {integrity: sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + '@babel/plugin-syntax-import-assertions@7.26.0': + resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.24.1': - resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1056,338 +1098,350 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.24.1': - resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==} + '@babel/plugin-transform-arrow-functions@7.25.9': + resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.24.3': - resolution: {integrity: sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==} + '@babel/plugin-transform-async-generator-functions@7.25.9': + resolution: {integrity: sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.24.1': - resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==} + '@babel/plugin-transform-async-to-generator@7.25.9': + resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.24.1': - resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==} + '@babel/plugin-transform-block-scoped-functions@7.26.5': + resolution: {integrity: sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.24.5': - resolution: {integrity: sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==} + '@babel/plugin-transform-block-scoping@7.25.9': + resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.24.1': - resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==} + '@babel/plugin-transform-class-properties@7.25.9': + resolution: {integrity: sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.24.4': - resolution: {integrity: sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==} + '@babel/plugin-transform-class-static-block@7.26.0': + resolution: {integrity: sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.24.5': - resolution: {integrity: sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==} + '@babel/plugin-transform-classes@7.25.9': + resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.24.1': - resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==} + '@babel/plugin-transform-computed-properties@7.25.9': + resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.24.5': - resolution: {integrity: sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==} + '@babel/plugin-transform-destructuring@7.25.9': + resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.24.1': - resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==} + '@babel/plugin-transform-dotall-regex@7.25.9': + resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.24.1': - resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==} + '@babel/plugin-transform-duplicate-keys@7.25.9': + resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dynamic-import@7.24.1': - resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9': + resolution: {integrity: sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.25.9': + resolution: {integrity: sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.24.1': - resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==} + '@babel/plugin-transform-exponentiation-operator@7.26.3': + resolution: {integrity: sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.24.1': - resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==} + '@babel/plugin-transform-export-namespace-from@7.25.9': + resolution: {integrity: sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.24.1': - resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==} + '@babel/plugin-transform-for-of@7.25.9': + resolution: {integrity: sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.24.1': - resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==} + '@babel/plugin-transform-function-name@7.25.9': + resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.24.1': - resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==} + '@babel/plugin-transform-json-strings@7.25.9': + resolution: {integrity: sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.24.1': - resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==} + '@babel/plugin-transform-literals@7.25.9': + resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.24.1': - resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==} + '@babel/plugin-transform-logical-assignment-operators@7.25.9': + resolution: {integrity: sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.24.1': - resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==} + '@babel/plugin-transform-member-expression-literals@7.25.9': + resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.24.1': - resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==} + '@babel/plugin-transform-modules-amd@7.25.9': + resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.24.1': - resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} + '@babel/plugin-transform-modules-commonjs@7.26.3': + resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.24.1': - resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==} + '@babel/plugin-transform-modules-systemjs@7.25.9': + resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.24.1': - resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==} + '@babel/plugin-transform-modules-umd@7.25.9': + resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5': - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': + resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.24.1': - resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==} + '@babel/plugin-transform-new-target@7.25.9': + resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.24.1': - resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==} + '@babel/plugin-transform-nullish-coalescing-operator@7.26.6': + resolution: {integrity: sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.24.1': - resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==} + '@babel/plugin-transform-numeric-separator@7.25.9': + resolution: {integrity: sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.24.5': - resolution: {integrity: sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==} + '@babel/plugin-transform-object-rest-spread@7.25.9': + resolution: {integrity: sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.24.1': - resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==} + '@babel/plugin-transform-object-super@7.25.9': + resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.24.1': - resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==} + '@babel/plugin-transform-optional-catch-binding@7.25.9': + resolution: {integrity: sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.24.5': - resolution: {integrity: sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==} + '@babel/plugin-transform-optional-chaining@7.25.9': + resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.24.5': - resolution: {integrity: sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==} + '@babel/plugin-transform-parameters@7.25.9': + resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.24.1': - resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==} + '@babel/plugin-transform-private-methods@7.25.9': + resolution: {integrity: sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.24.5': - resolution: {integrity: sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==} + '@babel/plugin-transform-private-property-in-object@7.25.9': + resolution: {integrity: sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.24.1': - resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==} + '@babel/plugin-transform-property-literals@7.25.9': + resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-constant-elements@7.24.1': - resolution: {integrity: sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==} + '@babel/plugin-transform-react-constant-elements@7.25.9': + resolution: {integrity: sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.24.1': - resolution: {integrity: sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==} + '@babel/plugin-transform-react-display-name@7.25.9': + resolution: {integrity: sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-development@7.22.5': - resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==} + '@babel/plugin-transform-react-jsx-development@7.25.9': + resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.23.4': - resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} + '@babel/plugin-transform-react-jsx@7.25.9': + resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-pure-annotations@7.24.1': - resolution: {integrity: sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==} + '@babel/plugin-transform-react-pure-annotations@7.25.9': + resolution: {integrity: sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.24.1': - resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==} + '@babel/plugin-transform-regenerator@7.25.9': + resolution: {integrity: sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-reserved-words@7.24.1': - resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==} + '@babel/plugin-transform-regexp-modifiers@7.26.0': + resolution: {integrity: sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.25.9': + resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.24.3': - resolution: {integrity: sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==} + '@babel/plugin-transform-runtime@7.25.9': + resolution: {integrity: sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.24.1': - resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==} + '@babel/plugin-transform-shorthand-properties@7.25.9': + resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.24.1': - resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==} + '@babel/plugin-transform-spread@7.25.9': + resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.24.1': - resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==} + '@babel/plugin-transform-sticky-regex@7.25.9': + resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.24.1': - resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==} + '@babel/plugin-transform-template-literals@7.25.9': + resolution: {integrity: sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.24.5': - resolution: {integrity: sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==} + '@babel/plugin-transform-typeof-symbol@7.25.9': + resolution: {integrity: sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.24.5': - resolution: {integrity: sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==} + '@babel/plugin-transform-typescript@7.26.5': + resolution: {integrity: sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.24.1': - resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==} + '@babel/plugin-transform-unicode-escapes@7.25.9': + resolution: {integrity: sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.24.1': - resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==} + '@babel/plugin-transform-unicode-property-regex@7.25.9': + resolution: {integrity: sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.24.1': - resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==} + '@babel/plugin-transform-unicode-regex@7.25.9': + resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.24.1': - resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==} + '@babel/plugin-transform-unicode-sets-regex@7.25.9': + resolution: {integrity: sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.24.5': - resolution: {integrity: sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==} + '@babel/preset-env@7.26.0': + resolution: {integrity: sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1397,57 +1451,310 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-react@7.24.1': - resolution: {integrity: sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==} + '@babel/preset-react@7.26.3': + resolution: {integrity: sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.24.1': - resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} + '@babel/preset-typescript@7.26.0': + resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - - '@babel/runtime-corejs3@7.24.5': - resolution: {integrity: sha512-GWO0mgzNMLWaSYM4z4NVIuY0Cd1fl8cPnuetuddu5w/qGuvt5Y7oUi/kvvQGK9xgOkFJDQX2heIvTRn/OQ1XTg==} + '@babel/runtime-corejs3@7.26.0': + resolution: {integrity: sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.24.5': - resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - '@babel/template@7.24.0': - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.5': - resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + '@babel/traverse@7.26.5': + resolution: {integrity: sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.24.5': - resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + '@babel/types@7.26.5': + resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@csstools/cascade-layer-name-parser@2.0.4': + resolution: {integrity: sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/color-helpers@5.0.1': + resolution: {integrity: sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.1': + resolution: {integrity: sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-color-parser@3.0.7': + resolution: {integrity: sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} + engines: {node: '>=18'} + + '@csstools/media-query-list-parser@4.0.2': + resolution: {integrity: sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/postcss-cascade-layers@5.0.1': + resolution: {integrity: sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function@4.0.7': + resolution: {integrity: sha512-aDHYmhNIHR6iLw4ElWhf+tRqqaXwKnMl0YsQ/X105Zc4dQwe6yJpMrTN6BwOoESrkDjOYMOfORviSSLeDTJkdQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-function@3.0.7': + resolution: {integrity: sha512-e68Nev4CxZYCLcrfWhHH4u/N1YocOfTmw67/kVX5Rb7rnguqqLyxPjhHWjSBX8o4bmyuukmNf3wrUSU3//kT7g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-content-alt-text@2.0.4': + resolution: {integrity: sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-exponential-functions@2.0.6': + resolution: {integrity: sha512-IgJA5DQsQLu/upA3HcdvC6xEMR051ufebBTIXZ5E9/9iiaA7juXWz1ceYj814lnDYP/7eWjZnw0grRJlX4eI6g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-font-format-keywords@4.0.0': + resolution: {integrity: sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gamut-mapping@2.0.7': + resolution: {integrity: sha512-gzFEZPoOkY0HqGdyeBXR3JP218Owr683u7KOZazTK7tQZBE8s2yhg06W1tshOqk7R7SWvw9gkw2TQogKpIW8Xw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gradients-interpolation-method@5.0.7': + resolution: {integrity: sha512-WgEyBeg6glUeTdS2XT7qeTFBthTJuXlS9GFro/DVomj7W7WMTamAwpoP4oQCq/0Ki2gvfRYFi/uZtmRE14/DFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-hwb-function@4.0.7': + resolution: {integrity: sha512-LKYqjO+wGwDCfNIEllessCBWfR4MS/sS1WXO+j00KKyOjm7jDW2L6jzUmqASEiv/kkJO39GcoIOvTTfB3yeBUA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-ic-unit@4.0.0': + resolution: {integrity: sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-initial@2.0.0': + resolution: {integrity: sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-is-pseudo-class@5.0.1': + resolution: {integrity: sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-light-dark-function@2.0.7': + resolution: {integrity: sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-float-and-clear@3.0.0': + resolution: {integrity: sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overflow@2.0.0': + resolution: {integrity: sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0': + resolution: {integrity: sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-resize@3.0.0': + resolution: {integrity: sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-viewport-units@3.0.3': + resolution: {integrity: sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-minmax@2.0.6': + resolution: {integrity: sha512-J1+4Fr2W3pLZsfxkFazK+9kr96LhEYqoeBszLmFjb6AjYs+g9oDAw3J5oQignLKk3rC9XHW+ebPTZ9FaW5u5pg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.4': + resolution: {integrity: sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-nested-calc@4.0.0': + resolution: {integrity: sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-normalize-display-values@4.0.0': + resolution: {integrity: sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-oklab-function@4.0.7': + resolution: {integrity: sha512-I6WFQIbEKG2IO3vhaMGZDkucbCaUSXMxvHNzDdnfsTCF5tc0UlV3Oe2AhamatQoKFjBi75dSEMrgWq3+RegsOQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-progressive-custom-properties@4.0.0': + resolution: {integrity: sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-random-function@1.0.2': + resolution: {integrity: sha512-vBCT6JvgdEkvRc91NFoNrLjgGtkLWt47GKT6E2UDn3nd8ZkMBiziQ1Md1OiKoSsgzxsSnGKG3RVdhlbdZEkHjA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-relative-color-syntax@3.0.7': + resolution: {integrity: sha512-apbT31vsJVd18MabfPOnE977xgct5B1I+Jpf+Munw3n6kKb1MMuUmGGH+PT9Hm/fFs6fe61Q/EWnkrb4bNoNQw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-scope-pseudo-class@4.0.1': + resolution: {integrity: sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-sign-functions@1.1.1': + resolution: {integrity: sha512-MslYkZCeMQDxetNkfmmQYgKCy4c+w9pPDfgOBCJOo/RI1RveEUdZQYtOfrC6cIZB7sD7/PHr2VGOcMXlZawrnA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-stepped-value-functions@4.0.6': + resolution: {integrity: sha512-/dwlO9w8vfKgiADxpxUbZOWlL5zKoRIsCymYoh1IPuBsXODKanKnfuZRr32DEqT0//3Av1VjfNZU9yhxtEfIeA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-text-decoration-shorthand@4.0.1': + resolution: {integrity: sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-trigonometric-functions@4.0.6': + resolution: {integrity: sha512-c4Y1D2Why/PeccaSouXnTt6WcNHJkoJRidV2VW9s5gJ97cNxnLgQ4Qj8qOqkIR9VmTQKJyNcbF4hy79ZQnWD7A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-unset-value@4.0.0': + resolution: {integrity: sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/selector-resolve-nested@3.0.0': + resolution: {integrity: sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/utilities@2.0.0': + resolution: {integrity: sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + '@discoveryjs/json-ext@0.5.7': resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} - '@docsearch/css@3.6.0': - resolution: {integrity: sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==} + '@docsearch/css@3.8.3': + resolution: {integrity: sha512-1nELpMV40JDLJ6rpVVFX48R1jsBFIQ6RnEQDsLFGmzOjPWTOMlZqUcXcvRx8VmYV/TqnS1l784Ofz+ZEb+wEOQ==} - '@docsearch/react@3.6.0': - resolution: {integrity: sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==} + '@docsearch/react@3.8.3': + resolution: {integrity: sha512-6UNrg88K7lJWmuS6zFPL/xgL+n326qXqZ7Ybyy4E8P/6Rcblk3GE8RXxeol4Pd5pFpKMhOhBhzABKKwHtbJCIg==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' react: '>= 16.8.0 < 19.0.0' @@ -1463,308 +1770,471 @@ packages: search-insights: optional: true - '@docusaurus/core@3.3.2': - resolution: {integrity: sha512-PzKMydKI3IU1LmeZQDi+ut5RSuilbXnA8QdowGeJEgU8EJjmx3rBHNT1LxQxOVqNEwpWi/csLwd9bn7rUjggPA==} + '@docusaurus/babel@3.7.0': + resolution: {integrity: sha512-0H5uoJLm14S/oKV3Keihxvh8RV+vrid+6Gv+2qhuzbqHanawga8tYnsdpjEyt36ucJjqlby2/Md2ObWjA02UXQ==} + engines: {node: '>=18.0'} + + '@docusaurus/bundler@3.7.0': + resolution: {integrity: sha512-CUUT9VlSGukrCU5ctZucykvgCISivct+cby28wJwCC/fkQFgAHRp/GKv2tx38ZmXb7nacrKzFTcp++f9txUYGg==} + engines: {node: '>=18.0'} + peerDependencies: + '@docusaurus/faster': '*' + peerDependenciesMeta: + '@docusaurus/faster': + optional: true + + '@docusaurus/core@3.7.0': + resolution: {integrity: sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ==} engines: {node: '>=18.0'} hasBin: true peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + '@mdx-js/react': ^3.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/cssnano-preset@3.3.2': - resolution: {integrity: sha512-+5+epLk/Rp4vFML4zmyTATNc3Is+buMAL6dNjrMWahdJCJlMWMPd/8YfU+2PA57t8mlSbhLJ7vAZVy54cd1vRQ==} + '@docusaurus/cssnano-preset@3.7.0': + resolution: {integrity: sha512-X9GYgruZBSOozg4w4dzv9uOz8oK/EpPVQXkp0MM6Tsgp/nRIU9hJzJ0Pxg1aRa3xCeEQTOimZHcocQFlLwYajQ==} engines: {node: '>=18.0'} - '@docusaurus/logger@3.3.2': - resolution: {integrity: sha512-Ldu38GJ4P8g4guN7d7pyCOJ7qQugG7RVyaxrK8OnxuTlaImvQw33aDRwaX2eNmX8YK6v+//Z502F4sOZbHHCHQ==} + '@docusaurus/logger@3.7.0': + resolution: {integrity: sha512-z7g62X7bYxCYmeNNuO9jmzxLQG95q9QxINCwpboVcNff3SJiHJbGrarxxOVMVmAh1MsrSfxWkVGv4P41ktnFsA==} engines: {node: '>=18.0'} - '@docusaurus/mdx-loader@3.3.2': - resolution: {integrity: sha512-AFRxj/aOk3/mfYDPxE3wTbrjeayVRvNSZP7mgMuUlrb2UlPRbSVAFX1k2RbgAJrnTSwMgb92m2BhJgYRfptN3g==} + '@docusaurus/mdx-loader@3.7.0': + resolution: {integrity: sha512-OFBG6oMjZzc78/U3WNPSHs2W9ZJ723ewAcvVJaqS0VgyeUfmzUV8f1sv+iUHA0DtwiR5T5FjOxj6nzEE8LY6VA==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/module-type-aliases@3.3.2': - resolution: {integrity: sha512-b/XB0TBJah5yKb4LYuJT4buFvL0MGAb0+vJDrJtlYMguRtsEBkf2nWl5xP7h4Dlw6ol0hsHrCYzJ50kNIOEclw==} + '@docusaurus/module-type-aliases@3.7.0': + resolution: {integrity: sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg==} peerDependencies: react: '*' react-dom: '*' - '@docusaurus/plugin-content-blog@3.3.2': - resolution: {integrity: sha512-fJU+dmqp231LnwDJv+BHVWft8pcUS2xVPZdeYH6/ibH1s2wQ/sLcmUrGWyIv/Gq9Ptj8XWjRPMghlxghuPPoxg==} + '@docusaurus/plugin-content-blog@3.7.0': + resolution: {integrity: sha512-EFLgEz6tGHYWdPU0rK8tSscZwx+AsyuBW/r+tNig2kbccHYGUJmZtYN38GjAa3Fda4NU+6wqUO5kTXQSRBQD3g==} + engines: {node: '>=18.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-docs@3.7.0': + resolution: {integrity: sha512-GXg5V7kC9FZE4FkUZA8oo/NrlRb06UwuICzI6tcbzj0+TVgjq/mpUXXzSgKzMS82YByi4dY2Q808njcBCyy6tQ==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-docs@3.3.2': - resolution: {integrity: sha512-Dm1ri2VlGATTN3VGk1ZRqdRXWa1UlFubjaEL6JaxaK7IIFqN/Esjpl+Xw10R33loHcRww/H76VdEeYayaL76eg==} + '@docusaurus/plugin-content-pages@3.7.0': + resolution: {integrity: sha512-YJSU3tjIJf032/Aeao8SZjFOrXJbz/FACMveSMjLyMH4itQyZ2XgUIzt4y+1ISvvk5zrW4DABVT2awTCqBkx0Q==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-pages@3.3.2': - resolution: {integrity: sha512-EKc9fQn5H2+OcGER8x1aR+7URtAGWySUgULfqE/M14+rIisdrBstuEZ4lUPDRrSIexOVClML82h2fDS+GSb8Ew==} + '@docusaurus/plugin-debug@3.7.0': + resolution: {integrity: sha512-Qgg+IjG/z4svtbCNyTocjIwvNTNEwgRjSXXSJkKVG0oWoH0eX/HAPiu+TS1HBwRPQV+tTYPWLrUypYFepfujZA==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-debug@3.3.2': - resolution: {integrity: sha512-oBIBmwtaB+YS0XlmZ3gCO+cMbsGvIYuAKkAopoCh0arVjtlyPbejzPrHuCoRHB9G7abjNZw7zoONOR8+8LM5+Q==} + '@docusaurus/plugin-google-analytics@3.7.0': + resolution: {integrity: sha512-otIqiRV/jka6Snjf+AqB360XCeSv7lQC+DKYW+EUZf6XbuE8utz5PeUQ8VuOcD8Bk5zvT1MC4JKcd5zPfDuMWA==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-analytics@3.3.2': - resolution: {integrity: sha512-jXhrEIhYPSClMBK6/IA8qf1/FBoxqGXZvg7EuBax9HaK9+kL3L0TJIlatd8jQJOMtds8mKw806TOCc3rtEad1A==} + '@docusaurus/plugin-google-gtag@3.7.0': + resolution: {integrity: sha512-M3vrMct1tY65ModbyeDaMoA+fNJTSPe5qmchhAbtqhDD/iALri0g9LrEpIOwNaoLmm6lO88sfBUADQrSRSGSWA==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-gtag@3.3.2': - resolution: {integrity: sha512-vcrKOHGbIDjVnNMrfbNpRQR1x6Jvcrb48kVzpBAOsKbj9rXZm/idjVAXRaewwobHdOrJkfWS/UJoxzK8wyLRBQ==} + '@docusaurus/plugin-google-tag-manager@3.7.0': + resolution: {integrity: sha512-X8U78nb8eiMiPNg3jb9zDIVuuo/rE1LjGDGu+5m5CX4UBZzjMy+klOY2fNya6x8ACyE/L3K2erO1ErheP55W/w==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-tag-manager@3.3.2': - resolution: {integrity: sha512-ldkR58Fdeks0vC+HQ+L+bGFSJsotQsipXD+iKXQFvkOfmPIV6QbHRd7IIcm5b6UtwOiK33PylNS++gjyLUmaGw==} + '@docusaurus/plugin-sitemap@3.7.0': + resolution: {integrity: sha512-bTRT9YLZ/8I/wYWKMQke18+PF9MV8Qub34Sku6aw/vlZ/U+kuEuRpQ8bTcNOjaTSfYsWkK4tTwDMHK2p5S86cA==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-sitemap@3.3.2': - resolution: {integrity: sha512-/ZI1+bwZBhAgC30inBsHe3qY9LOZS+79fRGkNdTcGHRMcdAp6Vw2pCd1gzlxd/xU+HXsNP6cLmTOrggmRp3Ujg==} + '@docusaurus/plugin-svgr@3.7.0': + resolution: {integrity: sha512-HByXIZTbc4GV5VAUkZ2DXtXv1Qdlnpk3IpuImwSnEzCDBkUMYcec5282hPjn6skZqB25M1TYCmWS91UbhBGxQg==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/preset-classic@3.3.2': - resolution: {integrity: sha512-1SDS7YIUN1Pg3BmD6TOTjhB7RSBHJRpgIRKx9TpxqyDrJ92sqtZhomDc6UYoMMLQNF2wHFZZVGFjxJhw2VpL+Q==} + '@docusaurus/preset-classic@3.7.0': + resolution: {integrity: sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 '@docusaurus/react-loadable@6.0.0': resolution: {integrity: sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==} peerDependencies: react: '*' - '@docusaurus/theme-classic@3.3.2': - resolution: {integrity: sha512-gepHFcsluIkPb4Im9ukkiO4lXrai671wzS3cKQkY9BXQgdVwsdPf/KS0Vs4Xlb0F10fTz+T3gNjkxNEgSN9M0A==} + '@docusaurus/theme-classic@3.7.0': + resolution: {integrity: sha512-MnLxG39WcvLCl4eUzHr0gNcpHQfWoGqzADCly54aqCofQX6UozOS9Th4RK3ARbM9m7zIRv3qbhggI53dQtx/hQ==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-common@3.3.2': - resolution: {integrity: sha512-kXqSaL/sQqo4uAMQ4fHnvRZrH45Xz2OdJ3ABXDS7YVGPSDTBC8cLebFrRR4YF9EowUHto1UC/EIklJZQMG/usA==} + '@docusaurus/theme-common@3.7.0': + resolution: {integrity: sha512-8eJ5X0y+gWDsURZnBfH0WabdNm8XMCXHv8ENy/3Z/oQKwaB/EHt5lP9VsTDTf36lKEp0V6DjzjFyFIB+CetL0A==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-search-algolia@3.3.2': - resolution: {integrity: sha512-qLkfCl29VNBnF1MWiL9IyOQaHxUvicZp69hISyq/xMsNvFKHFOaOfk9xezYod2Q9xx3xxUh9t/QPigIei2tX4w==} + '@docusaurus/theme-search-algolia@3.7.0': + resolution: {integrity: sha512-Al/j5OdzwRU1m3falm+sYy9AaB93S1XF1Lgk9Yc6amp80dNxJVplQdQTR4cYdzkGtuQqbzUA8+kaoYYO0RbK6g==} engines: {node: '>=18.0'} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-translations@3.3.2': - resolution: {integrity: sha512-bPuiUG7Z8sNpGuTdGnmKl/oIPeTwKr0AXLGu9KaP6+UFfRZiyWbWE87ti97RrevB2ffojEdvchNujparR3jEZQ==} + '@docusaurus/theme-translations@3.7.0': + resolution: {integrity: sha512-Ewq3bEraWDmienM6eaNK7fx+/lHMtGDHQyd1O+4+3EsDxxUmrzPkV7Ct3nBWTuE0MsoZr3yNwQVKjllzCMuU3g==} engines: {node: '>=18.0'} - '@docusaurus/types@3.3.2': - resolution: {integrity: sha512-5p201S7AZhliRxTU7uMKtSsoC8mgPA9bs9b5NQg1IRdRxJfflursXNVsgc3PcMqiUTul/v1s3k3rXXFlRE890w==} + '@docusaurus/types@3.7.0': + resolution: {integrity: sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ==} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/utils-common@3.3.2': - resolution: {integrity: sha512-QWFTLEkPYsejJsLStgtmetMFIA3pM8EPexcZ4WZ7b++gO5jGVH7zsipREnCHzk6+eDgeaXfkR6UPaTt86bp8Og==} + '@docusaurus/utils-common@3.7.0': + resolution: {integrity: sha512-IZeyIfCfXy0Mevj6bWNg7DG7B8G+S6o6JVpddikZtWyxJguiQ7JYr0SIZ0qWd8pGNuMyVwriWmbWqMnK7Y5PwA==} engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true - '@docusaurus/utils-validation@3.3.2': - resolution: {integrity: sha512-itDgFs5+cbW9REuC7NdXals4V6++KifgVMzoGOOOSIifBQw+8ULhy86u5e1lnptVL0sv8oAjq2alO7I40GR7pA==} + '@docusaurus/utils-validation@3.7.0': + resolution: {integrity: sha512-w8eiKk8mRdN+bNfeZqC4nyFoxNyI1/VExMKAzD9tqpJfLLbsa46Wfn5wcKH761g9WkKh36RtFV49iL9lh1DYBA==} engines: {node: '>=18.0'} - '@docusaurus/utils@3.3.2': - resolution: {integrity: sha512-f4YMnBVymtkSxONv4Y8js3Gez9IgHX+Lcg6YRMOjVbq8sgCcdYK1lf6SObAuz5qB/mxiSK7tW0M9aaiIaUSUJg==} + '@docusaurus/utils@3.7.0': + resolution: {integrity: sha512-e7zcB6TPnVzyUaHMJyLSArKa2AG3h9+4CfvKXKKWNx6hRs+p0a+u7HHTJBgo6KW2m+vqDnuIHK4X+bhmoghAFA==} engines: {node: '>=18.0'} - peerDependencies: - '@docusaurus/types': '*' - peerDependenciesMeta: - '@docusaurus/types': - optional: true '@es-joy/jsdoccomment@0.41.0': resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==} engines: {node: '>=16'} + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.19.5': resolution: {integrity: sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.19.5': resolution: {integrity: sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.19.5': resolution: {integrity: sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.19.5': resolution: {integrity: sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.19.5': resolution: {integrity: sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.19.5': resolution: {integrity: sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.19.5': resolution: {integrity: sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.19.5': resolution: {integrity: sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.19.5': resolution: {integrity: sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.19.5': resolution: {integrity: sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.19.5': resolution: {integrity: sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.19.5': resolution: {integrity: sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.19.5': resolution: {integrity: sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.19.5': resolution: {integrity: sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.19.5': resolution: {integrity: sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.19.5': resolution: {integrity: sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.19.5': resolution: {integrity: sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.19.5': resolution: {integrity: sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.19.5': resolution: {integrity: sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.19.5': resolution: {integrity: sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.19.5': resolution: {integrity: sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.19.5': resolution: {integrity: sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} '@hapi/hoek@9.3.0': @@ -1773,8 +2243,8 @@ packages: '@hapi/topo@5.1.0': resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead @@ -1786,32 +2256,79 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead - '@ipld/car@5.3.0': - resolution: {integrity: sha512-OB8LVvJeVAFFGluNIkZeDZ/aGeoekFKsuIvNT9I5sJIb5WekQuW5+lekjQ7Z7mZ7DBKuke/kI4jBT1j0/akU1w==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} + '@inquirer/checkbox@1.5.2': + resolution: {integrity: sha512-CifrkgQjDkUkWexmgYYNyB5603HhTHI91vLFeQXh6qrTKiCMVASol01Rs1cv6LP/A2WccZSRlJKZhbaBIs/9ZA==} + engines: {node: '>=14.18.0'} + + '@inquirer/confirm@2.0.17': + resolution: {integrity: sha512-EqzhGryzmGpy2aJf6LxJVhndxYmFs+m8cxXzf8nejb1DE3sabf6mUgBcp4J0jAUEiAcYzqmkqRr7LPFh/WdnXA==} + engines: {node: '>=14.18.0'} + + '@inquirer/core@5.1.2': + resolution: {integrity: sha512-w3PMZH5rahrukn8/I7P9Ihil+twgLTUHDZtJlJyBbUKyPaOSSQjLZkb0PpncVhin1gCaMgOFXy6iNPgcZUoo2w==} + engines: {node: '>=14.18.0'} + + '@inquirer/core@6.0.0': + resolution: {integrity: sha512-fKi63Khkisgda3ohnskNf5uZJj+zXOaBvOllHsOkdsXRA/ubQLJQrZchFFi57NKbZzkTunXiBMdvWOv71alonw==} + engines: {node: '>=14.18.0'} + + '@inquirer/editor@1.2.15': + resolution: {integrity: sha512-gQ77Ls09x5vKLVNMH9q/7xvYPT6sIs5f7URksw+a2iJZ0j48tVS6crLqm2ugG33tgXHIwiEqkytY60Zyh5GkJQ==} + engines: {node: '>=14.18.0'} + + '@inquirer/expand@1.1.16': + resolution: {integrity: sha512-TGLU9egcuo+s7PxphKUCnJnpCIVY32/EwPCLLuu+gTvYiD8hZgx8Z2niNQD36sa6xcfpdLY6xXDBiL/+g1r2XQ==} + engines: {node: '>=14.18.0'} + + '@inquirer/input@1.2.16': + resolution: {integrity: sha512-Ou0LaSWvj1ni+egnyQ+NBtfM1885UwhRCMtsRt2bBO47DoC1dwtCa+ZUNgrxlnCHHF0IXsbQHYtIIjFGAavI4g==} + engines: {node: '>=14.18.0'} + + '@inquirer/password@1.1.16': + resolution: {integrity: sha512-aZYZVHLUXZ2gbBot+i+zOJrks1WaiI95lvZCn1sKfcw6MtSSlYC8uDX8sTzQvAsQ8epHoP84UNvAIT0KVGOGqw==} + engines: {node: '>=14.18.0'} + + '@inquirer/prompts@3.3.2': + resolution: {integrity: sha512-k52mOMRvTUejrqyF1h8Z07chC+sbaoaUYzzr1KrJXyj7yaX7Nrh0a9vktv8TuocRwIJOQMaj5oZEmkspEcJFYQ==} + engines: {node: '>=14.18.0'} + + '@inquirer/rawlist@1.2.16': + resolution: {integrity: sha512-pZ6TRg2qMwZAOZAV6TvghCtkr53dGnK29GMNQ3vMZXSNguvGqtOVc4j/h1T8kqGJFagjyfBZhUPGwNS55O5qPQ==} + engines: {node: '>=14.18.0'} + + '@inquirer/select@1.3.3': + resolution: {integrity: sha512-RzlRISXWqIKEf83FDC9ZtJ3JvuK1l7aGpretf41BCWYrvla2wU8W8MTRNMiPrPJ+1SIqrRC1nZdZ60hD9hRXLg==} + engines: {node: '>=14.18.0'} + + '@inquirer/type@1.5.5': + resolution: {integrity: sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==} + engines: {node: '>=18'} - '@ipld/dag-cbor@9.2.0': - resolution: {integrity: sha512-N14oMy0q4gM6OuZkIpisKe0JBSjf1Jb39VI+7jMLiWX9124u1Z3Fdj/Tag1NA0cVxxqWDh0CqsjcVfOKtelPDA==} + '@ipld/car@5.4.0': + resolution: {integrity: sha512-FiGxOhTUh3fn/kkA+YvNYQjA/T8T5DcKG0NZwAi3aXrizN1qm99HzdYTccEwcX/rUCtI8wTUCKDNPBLUb7pBIQ==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@ipld/dag-cbor@9.2.1': - resolution: {integrity: sha512-nyY48yE7r3dnJVlxrdaimrbloh4RokQaNRdI//btfTkcTEZbpmSrbYcBQ4VKTf8ZxXAOUJy4VsRpkJo+y9RTnA==} + '@ipld/dag-cbor@9.2.2': + resolution: {integrity: sha512-uIEOuruCqKTP50OBWwgz4Js2+LhiBQaxc57cnP71f45b1mHEAo1OCR1Zn/TbvSW/mV1x+JqhacIktkKyaYqhCw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@ipld/dag-json@10.2.0': - resolution: {integrity: sha512-O9YLUrl3d3WbVz7v1WkajFkyfOLEe2Fep+wor4fgVe0ywxzrivrj437NiPcVyB+2EDdFn/Q7tCHFf8YVhDf8ZA==} + '@ipld/dag-json@10.2.3': + resolution: {integrity: sha512-itacv1j1hvYgLox2B42Msn70QLzcr0MEo5yGIENuw2SM/lQzq9bmBiMky+kDsIrsqqblKTXcHBZnnmK7D4a6ZQ==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@ipld/dag-pb@4.1.0': - resolution: {integrity: sha512-LJU451Drqs5zjFm7jI4Hs3kHlilOqkjcSfPiQgVsZnWaYb2C7YdfhnclrVn/X+ucKejlU9BL3+gXFCZUXkMuCg==} + '@ipld/dag-pb@4.1.3': + resolution: {integrity: sha512-ueULCaaSCcD+dQga6nKiRr+RSeVgdiYiEPKVUu5iQMNYDN+9osd0KpR3UDd9uQQ+6RWuv9L34SchfEwj7YIbOA==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@ipld/dag-ucan@3.4.0': - resolution: {integrity: sha512-sW4R43w3DbEdoGWWJZCwsblwXa600HCanG9p2w1MJPVBNTNjhvqc3XI0uEqKhT2oqKWrND7uInVtcPmZme7hhA==} + '@ipld/dag-ucan@3.4.5': + resolution: {integrity: sha512-wiWhH0Ju7WgnumsarHCYtlo+1NRy+WIsXyAB7g2sDqVsKCyEJiLLmjeZzKqNv+qMxLnUS8bQ287cPiQ//s/oJQ==} '@ipld/unixfs@2.2.0': resolution: {integrity: sha512-lDQ2eRhJlbFaBoO3bhOmDVCLmpOnhwtwbilqUgAAhbhoPSmLrnv7gsBuToZjXOdPaEGSL7apkmm6nFrcU6zh4Q==} + '@ipld/unixfs@3.0.0': + resolution: {integrity: sha512-Tj3/BPOlnemcZQ2ETIZAO8hqAs9KNzWyX5J9+JCL9jDwvYwjxeYjqJ3v+9DusNvTBmJhZnGVP6ijUHrsuOLp+g==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1828,8 +2345,8 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} '@jridgewell/resolve-uri@3.1.2': @@ -1843,8 +2360,8 @@ packages: '@jridgewell/source-map@0.3.6': resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1852,11 +2369,11 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@mdx-js/mdx@3.0.1': - resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} + '@mdx-js/mdx@3.1.0': + resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} - '@mdx-js/react@3.0.1': - resolution: {integrity: sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==} + '@mdx-js/react@3.1.0': + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} peerDependencies: '@types/react': '>=16' react: '>=16' @@ -1865,15 +2382,16 @@ packages: resolution: {integrity: sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - '@noble/curves@1.4.0': - resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} '@noble/ed25519@1.7.3': resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -1902,15 +2420,15 @@ packages: resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} engines: {node: '>=12.22.0'} - '@pnpm/npm-conf@2.2.2': - resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} engines: {node: '>=12'} '@polka/url@0.5.0': resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==} - '@polka/url@1.0.0-next.25': - resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -1942,11 +2460,11 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@scure/base@1.1.6': - resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==} + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} - '@scure/bip39@1.3.0': - resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -1972,23 +2490,26 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@sinonjs/commons@2.0.0': - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} - '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@sinonjs/fake-timers@11.2.2': - resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + '@sinonjs/fake-timers@11.3.1': + resolution: {integrity: sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==} - '@sinonjs/samsam@8.0.0': - resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + '@sinonjs/samsam@8.0.2': + resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} - '@sinonjs/text-encoding@0.7.2': - resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} + '@sinonjs/text-encoding@0.7.3': + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + + '@slorber/react-helmet-async@1.3.0': + resolution: {integrity: sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@slorber/remark-comment@1.0.0': resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} @@ -2085,8 +2606,8 @@ packages: '@types/acorn@4.0.6': resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} - '@types/assert@1.5.10': - resolution: {integrity: sha512-qEO+AUgYab7GVbeDDgUNCU3o0aZUoIMpNAe+w5LDbRxfxQX7vQAdDgwj1AroX+i8KaV56FWg0srXlSZROnsrIQ==} + '@types/assert@1.5.11': + resolution: {integrity: sha512-FjS1mxq2dlGr9N4z72/DO+XmyRS3ZZIoVn998MEopAN/OmyN28F4yumRL5pOw2z+hbFLuWGYuF2rrw5p11xM5A==} '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} @@ -2094,6 +2615,9 @@ packages: '@types/bonjour@3.5.13': resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + '@types/configstore@6.0.2': + resolution: {integrity: sha512-OS//b51j9uyR3zvwD04Kfs5kHpve2qalQ18JhY/ho3voGYUTPLEG90/ocfKPI48hyHH8T04f7KEEbK6Ue60oZQ==} + '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} @@ -2106,17 +2630,20 @@ packages: '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - '@types/eslint@8.56.10': - resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - '@types/express-serve-static-core@4.19.0': - resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==} + '@types/express-serve-static-core@5.0.5': + resolution: {integrity: sha512-GLZPrd9ckqEBFMcVM/qRFAP0Hg3qiVEojgEFsx/N/zKXsBzbGF6z5FBDpZ0+Xhp1xr+qRZYjfGr1cWHB9oFHSA==} '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} @@ -2139,8 +2666,8 @@ packages: '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - '@types/http-proxy@1.17.14': - resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==} + '@types/http-proxy@1.17.15': + resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} '@types/inquirer@9.0.7': resolution: {integrity: sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==} @@ -2157,8 +2684,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/mdast@4.0.3': - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} @@ -2169,11 +2696,14 @@ packages: '@types/minimatch@3.0.5': resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - '@types/mocha@10.0.6': - resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==} + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - '@types/ms@0.7.34': - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} '@types/node-forge@1.3.11': resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} @@ -2181,20 +2711,17 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@20.12.10': - resolution: {integrity: sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==} + '@types/node@20.17.14': + resolution: {integrity: sha512-w6qdYetNL5KRBiSClK/KWai+2IMEJuAj+EujKCumalFOwXtvOXaEan9AuwcRID2IcOIAWSIfR495hBtgKlx2zg==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/prismjs@1.26.4': - resolution: {integrity: sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==} - - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + '@types/prismjs@1.26.5': + resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + '@types/qs@6.9.18': + resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -2208,8 +2735,8 @@ packages: '@types/react-router@5.1.20': resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} - '@types/react@18.3.1': - resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} + '@types/react@19.0.7': + resolution: {integrity: sha512-MoFsEJKkAtZCrC1r6CM8U22GzhG7u2Wir8ons/aCKH6MBdD1ibV24zOSSkdZVUKqN5i396zG5VKLYZ3yaUZdLA==} '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} @@ -2244,23 +2771,29 @@ packages: '@types/through@0.0.33': resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} - '@types/unist@2.0.10': - resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - '@types/unist@3.0.2': - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/update-notifier@6.0.8': + resolution: {integrity: sha512-IlDFnfSVfYQD+cKIg63DEXn3RFmd7W1iYtKQsJodcHK9R1yr8aKbKaPKfBxzPpcHCq2DU8zUq4PIPmy19Thjfg==} '@types/varint@6.0.3': resolution: {integrity: sha512-DHukoGWdJ2aYkveZJTB2rN2lp6m7APzVsoJQ7j/qy1fQxyamJTPD5xQzCMoJ2Qtgn0mE3wWeNOpbTyBFvF+dyA==} - '@types/ws@8.5.10': - resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + + '@types/ws@8.5.13': + resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} '@typescript-eslint/eslint-plugin@6.21.0': resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} @@ -2323,41 +2856,41 @@ packages: '@ucanto/client@9.0.1': resolution: {integrity: sha512-cV8w3AnaZaYCdUmyFFICj8YhFckDoy2DvWgAzGDMkPz0WbUW4lw9Tjm4hEE8x5kiP47wYej/pHKWCcoELiU0qw==} - '@ucanto/core@10.0.1': - resolution: {integrity: sha512-1BfUaJu0/c9Rl/WdZSDbScJJLsPsPe1g4ynl5kubUj3xDD/lyp/Q12PQVQ2X7hDiWwkpwmxCkRMkOxwc70iNKQ==} + '@ucanto/core@10.2.1': + resolution: {integrity: sha512-tPLrQUQEbo4d+vFB7hZdbMYaFqqJwczGz3LiGZMW7uWC9g1imFryJcedeLBqiKNYdQmBY70Yuj9QFDEope6mfQ==} - '@ucanto/interface@10.0.1': - resolution: {integrity: sha512-+Vr/N4mLsdynV9/bqtdFiq7WsUf3265/Qx2aHJmPtXo9/QvWKthJtpe0g8U4NWkWpVfqIFvyAO2db6D9zWQfQw==} + '@ucanto/interface@10.1.1': + resolution: {integrity: sha512-FHSA7eAN1pbJyzcMRFs9ioHlPQUpE3CfHxLGkCF9AU4HMl7G2YdgzeeOdiD3Li7Ur7EFUwEhZDoVMNKGH+7h1g==} - '@ucanto/principal@9.0.1': - resolution: {integrity: sha512-8eAvaZHW1vyET4X90rkJv6pmW1IOdEYlZYwO3wDgTkC5m9VytBEywCvpzP57cavdYIbbPse5QS9nMEGvk87zhw==} + '@ucanto/principal@9.0.2': + resolution: {integrity: sha512-RE3Rj0oz4wh4C9p2JJZB9+QLd7Fi3lCixrbHgAvEoSyTNpvz6ky8DGNtttmD5j3O94z13qdVdIoSRY6DQZXfAg==} - '@ucanto/server@10.0.0': - resolution: {integrity: sha512-JMDMT3tFRE0S1cdtx/Hhh7v9FizV6IS0fPrh6pcli7AzKvXVy8Xu6EQ/66Fax4AQM2tkGxNNxjj2wHM7P4CqAg==} + '@ucanto/server@10.1.0': + resolution: {integrity: sha512-R3m4QXtspVfPhEo07hnDgZVaebmMcgGcwAdn/rWVp2KGT0AGNyc5hMeTqzDwtJ2s4eqC2Zth3tkt/F71hNQLGg==} '@ucanto/transport@9.1.1': resolution: {integrity: sha512-3CR17nEemOVaTuMZa6waWgVL4sLxSPcxYvpaNeJ6NZo1rfsqdyRXOtbVV/RcI2BtUL0Cao6JM6P9+gdghfc5ng==} - '@ucanto/validator@9.0.2': - resolution: {integrity: sha512-LxhRbDMIoLt9LYHq/Rz1WCEH8AtmdsBTS/it28Ij/A3W0zyoSwUpAUxBtXaKRh/gpbxdWmjxX+nVfFJYL//b4g==} + '@ucanto/validator@9.0.3': + resolution: {integrity: sha512-S3NJ2fDhdnPuepAW7OVN/ngZ9DGqhibdwnFbs7lRyCNMgVrU90eqrQLa+8FmIhjlsWeQQvc77SUVygso2eqY4A==} - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@ungap/structured-clone@1.2.1': + resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - '@vue/compiler-core@3.4.27': - resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-dom@3.4.27': - resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - '@vue/compiler-sfc@3.4.27': - resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-ssr@3.4.27': - resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} - '@vue/shared@3.4.27': - resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} '@web-std/blob@3.0.5': resolution: {integrity: sha512-Lm03qr0eT3PoLBuhkvFBLf0EFkAsNz/G/AYCzpOdi483aFaVX86b4iQs0OHhzHJfN5C15q17UtDbyABjlzM96A==} @@ -2365,71 +2898,97 @@ packages: '@web-std/stream@1.0.0': resolution: {integrity: sha512-jyIbdVl+0ZJyKGTV0Ohb9E6UnxP+t7ZzX4Do3AHjZKxUXKMs9EmqnBDQgHF7bEw0EzbQygOjtt/7gvtmi//iCQ==} + '@web3-storage/access@20.1.1': + resolution: {integrity: sha512-W2C9sn8NTWw7zIUVzEk5MtwWQLFsOREF6Ju6VK+MYcuAkQ6yVll6Q7YtB5zLPwu29xJ7KIR6e5KzbDNSXHSfrA==} + + '@web3-storage/blob-index@1.0.5': + resolution: {integrity: sha512-mhzupWeRfxLljoULcagU++mOmQOriCBMKniUhsmrCXrtRV8voF7op/ymqix1f9uX1M5iB93YXcfxAVBwGWWKoA==} + engines: {node: '>=16.15'} + + '@web3-storage/capabilities@17.4.1': + resolution: {integrity: sha512-GogLfON8PZabi03CUyncBvMcCi36yQ/0iR5P8kr4pxdnZm7OuAn4sEwbEB8rTKbah5V10Vwgb3O5dh0FBgyjHg==} + + '@web3-storage/capabilities@18.0.1': + resolution: {integrity: sha512-FLAUpuuFYkLrMkXy/W7iVNQdFlqGCZUrQr30L2C05SbQdpb/4tN6jqRG+l2nvAYTaYjWTYzsYLHGy2illsuNZQ==} + '@web3-storage/content-claims@4.0.5': resolution: {integrity: sha512-+WpCkTN8aRfUCrCm0kOMZad+FRnFymVDFvS6/+PJMPGP17cci1/c5lqYdrjFV+5MkhL+BkUJVtRTx02G31FHmQ==} - '@web3-storage/content-claims@5.0.0': - resolution: {integrity: sha512-HJFRFsR0qHCe0cOERsb3AjAxxzohYMMoIWaGJgrShDycnl6yqXHrGcdua1BWUDu5pmvKzwD9D7VmI8aSfrCcRA==} + '@web3-storage/content-claims@5.1.3': + resolution: {integrity: sha512-X+Cpm+EmGuEvFyM8oX1NqsBkuSje836B72yuvnVmgd80XPt+McpOhM6ko7rfs9Dx9UmpiZq+998jlvBhg2W5ZA==} - '@web3-storage/content-claims@5.1.0': - resolution: {integrity: sha512-3VStFKoeieRpRU7brFjKTsAuAffQzYDIZ8F3Gh0+niw+MgzBK72osW+fftdquT8neWir34Ndu3mBUKKJ3ck1RQ==} + '@web3-storage/data-segment@5.3.0': + resolution: {integrity: sha512-zFJ4m+pEKqtKatJNsFrk/2lHeFSbkXZ6KKXjBe7/2ayA9wAar7T/unewnOcZrrZTnCWmaxKsXWqdMFy9bXK9dw==} - '@web3-storage/data-segment@4.0.0': - resolution: {integrity: sha512-AnNyJp3wHMa7LBzguQzm4rmXSi8vQBz4uFs+jiXnSNtLR5dAqHfhMvi9XdWonWPYvxNvT5ZhYCSF0mpDjymqKg==} + '@web3-storage/did-mailto@2.1.0': + resolution: {integrity: sha512-TRmfSXj1IhtX3ESurSNOylZSBKi0z/VJNoMLpof+AVRdovgZjjocpiePQTs2pfHKqHTHfJXc9AboWyK4IKTWMw==} + engines: {node: '>=16.15'} - '@web3-storage/data-segment@5.1.0': - resolution: {integrity: sha512-FYdmtKvNiVz+maZ++k4PdD43rfJW5DeagLpstq2y84CyOKNRBWbHLCZ/Ec5zT9iGI+0WgsCGbpC/WlG0jlrnhA==} + '@web3-storage/filecoin-api@8.0.0': + resolution: {integrity: sha512-f6Tq28i8nA27vpNnfxPuO+gMTrioB1U16m7zv+qC6SiKWRlEUfKUQbNaPDVguwviGZZWRHM1jDSyVuMuwWAdUA==} + engines: {node: '>=16.15'} - '@web3-storage/data-segment@5.2.0': - resolution: {integrity: sha512-Jr/bdweoEQ0lWIaNuFcYxM6BHYmXHBWwfXygHyp370agkAdU+dIFIbm+tX+66XP/1YmEUi4JI2I80psDtoJ++Q==} + '@web3-storage/filecoin-client@3.3.5': + resolution: {integrity: sha512-3JFKnHFizlljRSJyyCdNN3Np4MN5riBvjAXweqNmu4s2sChMB8kopnCkAFoMeEom9r7ZAnBAkMO3Wacjs6Nlcw==} '@web3-storage/sigv4@1.0.2': resolution: {integrity: sha512-ZUXKK10NmuQgPkqByhb1H3OQxkIM0CIn2BMPhGQw7vQw8WIzrBkk9IJiAVfJ/UVBFrf6uzPbx2lEBLt4diCMnQ==} - '@webassemblyjs/ast@1.12.1': - resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + '@web3-storage/upload-api@19.0.0': + resolution: {integrity: sha512-Hu0u77kKhwAfEviuxR2df7LuER5GKTyOIZoqo7U6RAZd3bkwBU5z7ebltj+tPxhpv4PeF7Jna2h9Mi+ujgI+MQ==} + engines: {node: '>=16.15'} + + '@web3-storage/upload-client@17.1.3': + resolution: {integrity: sha512-pOD5EM6RJgsJ3gRZWfhwfbD21OLvNQ239aD4D5BsQsEEgEoqR8aXdrjDWU4T8DA4YXU6VIai/VGIsDXgw+eg7g==} + + '@web3-storage/w3up-client@16.5.2': + resolution: {integrity: sha512-yJNh3r2QWZbn2jQ1ZfsnDJ1HIyhv9akEXeFWx+xFxKViT6df8IzT6BtCnxxFL2ED3Tx7rKVVG1pNatKRO3T+Uw==} + engines: {node: '>=18'} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - '@webassemblyjs/floating-point-hex-parser@1.11.6': - resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - '@webassemblyjs/helper-api-error@1.11.6': - resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - '@webassemblyjs/helper-buffer@1.12.1': - resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - '@webassemblyjs/helper-numbers@1.11.6': - resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - '@webassemblyjs/helper-wasm-bytecode@1.11.6': - resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - '@webassemblyjs/helper-wasm-section@1.12.1': - resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - '@webassemblyjs/ieee754@1.11.6': - resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - '@webassemblyjs/leb128@1.11.6': - resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - '@webassemblyjs/utf8@1.11.6': - resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - '@webassemblyjs/wasm-edit@1.12.1': - resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - '@webassemblyjs/wasm-gen@1.12.1': - resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - '@webassemblyjs/wasm-opt@1.12.1': - resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - '@webassemblyjs/wasm-parser@1.12.1': - resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - '@webassemblyjs/wast-printer@1.12.1': - resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -2444,11 +3003,6 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} - peerDependencies: - acorn: ^8 - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -2458,12 +3012,12 @@ packages: resolution: {integrity: sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ==} engines: {node: '>=0.4.0'} - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -2478,10 +3032,6 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - aggregate-error@4.0.1: - resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} - engines: {node: '>=12'} - ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -2503,24 +3053,29 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.13.0: - resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - algoliasearch-helper@3.19.0: - resolution: {integrity: sha512-AaSb5DZDMZmDQyIy6lf4aL0OZGgyIdqvLIIvSuVQOIOqfhrYSY7TvotIFI2x0Q3cP3xUpTd7lI1astUC4aXBJw==} + algoliasearch-helper@3.23.1: + resolution: {integrity: sha512-j/dF2ZELJBm4SJTK5ECsMuCDJpBB8ITiWKRjd3S15bK2bqrXKLWqDiA5A96WhVvCpZ2NmgNlUYmFbKOfcqivbg==} peerDependencies: algoliasearch: '>= 3.1 < 6' - algoliasearch@4.23.3: - resolution: {integrity: sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==} + algoliasearch@5.20.0: + resolution: {integrity: sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==} + engines: {node: '>= 14.0.0'} ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + ansi-escapes@5.0.0: resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} engines: {node: '>=12'} @@ -2529,22 +3084,34 @@ packages: resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} engines: {node: '>=14.16'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} engines: {'0': node >= 0.8.0} hasBin: true + ansi-regex@1.1.1: + resolution: {integrity: sha512-q5i8bFLg2wDfsuR56c1NzlJFPzVD+9mxhDrhqOGigEFa87OZHlF+9dWeGWzVTP/0ECiA/JUGzfzRr2t3eYORRw==} + engines: {node: '>=0.10.0'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-sequence-parser@1.1.1: resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -2557,8 +3124,8 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - ansicolors@0.3.2: - resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} any-signal@3.0.1: resolution: {integrity: sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg==} @@ -2567,6 +3134,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + archy@0.0.2: + resolution: {integrity: sha512-8mMsetjXv4pCPTrMbPPO2cxy9vzJn2jwbd+ug+mf8fEUZG2E78Vo5erJMjrnGuLTKqOLtS5ulFHJSfg1yaCjxA==} + are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -2580,8 +3150,8 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} array-differ@3.0.0: @@ -2595,8 +3165,8 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} arrify@2.0.1: @@ -2606,8 +3176,8 @@ packages: assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - astring@1.8.6: - resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true at-least-node@1.0.0: @@ -2617,8 +3187,8 @@ packages: atomically@2.0.3: resolution: {integrity: sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==} - autoprefixer@10.4.19: - resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -2628,8 +3198,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - babel-loader@9.1.3: - resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} engines: {node: '>= 14.15.0'} peerDependencies: '@babel/core': ^7.12.0 @@ -2638,18 +3208,18 @@ packages: babel-plugin-dynamic-import-node@2.3.3: resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} - babel-plugin-polyfill-corejs2@0.4.11: - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + babel-plugin-polyfill-corejs2@0.4.12: + resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.10.4: - resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.2: - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + babel-plugin-polyfill-regenerator@0.6.3: + resolution: {integrity: sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -2665,6 +3235,10 @@ packages: batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -2683,12 +3257,12 @@ packages: resolution: {integrity: sha512-5ZZB5nh6kErcjZ/CTK6lCwTIGlPdkTXbD8+2xLC4Fm0WGh7g2e2lW2bfURw7mvnPtSX1xV+sN4V2ndowSgIiHQ==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - bonjour-service@1.2.1: - resolution: {integrity: sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==} + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2701,14 +3275,22 @@ packages: resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + bplist-parser@0.2.0: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} + engines: {node: '>= 5.10.0'} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} browser-readablestream-to-it@1.0.3: @@ -2717,8 +3299,8 @@ packages: browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2732,6 +3314,10 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + bundle-name@3.0.0: + resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} + engines: {node: '>=12'} + bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -2740,8 +3326,8 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - c8@10.1.2: - resolution: {integrity: sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==} + c8@10.1.3: + resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -2768,8 +3354,16 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} engines: {node: '>= 0.4'} callsite@1.0.0: @@ -2797,26 +3391,26 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001616: - resolution: {integrity: sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==} - - cardinal@2.1.1: - resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} - hasBin: true + caniuse-lite@1.0.30001695: + resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==} carstream@1.1.1: resolution: {integrity: sha512-cgn3TqHo6SPsHBTfM5QgXngv6HtwgO1bKCHcdS35vBrweLcYrIG/+UboCbvnIGA0k8NtAYl/DvDdej/9pZGZxQ==} - carstream@2.1.0: - resolution: {integrity: sha512-4kYIT1Y+GW/+o6wxS2tZlKnnINcgm4ceODBmyoLNaiQ17G2FNmzvUnQnVQkugC4NORTMCzD6KZEMT534XMJ4Yw==} + carstream@2.3.0: + resolution: {integrity: sha512-2YwFg5Kxs2tqVCJv7sthWbYoUpALCYBBfTdpQcpicV7ipi6bBb1h9M4MNb1vm+724f39lUNp5VWhW43IFxfPlA==} - cborg@4.2.0: - resolution: {integrity: sha512-q6cFW5m3KxfP/9xGI3yGLaC1l5DP6DWM9IvjiJojnIwohL5CQDl02EXViPV852mOfQo+7PJGPN01MI87vFGzyA==} + cborg@4.2.7: + resolution: {integrity: sha512-zHTUAm+HAoRLtGEQ1b28HXBm8d/5YP+7eiSKzEu/mpFkptGYaMQCHv15OiQBuyNlIgbCBXvBbZQPl3xvcZTJXg==} hasBin: true ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@1.0.0: + resolution: {integrity: sha512-1TE3hpADga5iWinlcCpyhC7fTl9uQumLD8i2jJoJeVg7UbveY5jj7F6uCq8w0hQpSeLhaPn5QFe8e56toMVP1A==} + engines: {node: '>=0.10.0'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2829,6 +3423,10 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -2845,6 +3443,9 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -2852,16 +3453,12 @@ packages: resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} engines: {node: '>= 6'} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} ci-info@3.9.0: @@ -2876,10 +3473,6 @@ packages: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} - clean-stack@4.2.0: - resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} - engines: {node: '>=12'} - cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -2888,18 +3481,27 @@ packages: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} - cli-table3@0.6.4: - resolution: {integrity: sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} cli-truncate@3.1.0: resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -2978,8 +3580,8 @@ packages: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} - compression@1.7.4: - resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + compression@1.7.5: + resolution: {integrity: sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==} engines: {node: '>= 0.8.0'} concat-map@0.0.1: @@ -2996,12 +3598,17 @@ packages: resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} engines: {node: '>=12'} + configstore@7.0.0: + resolution: {integrity: sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ==} + engines: {node: '>=18'} + connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} - consola@2.15.3: - resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} content-disposition@0.5.2: resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} @@ -3021,8 +3628,8 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} copy-file@11.0.0: @@ -3039,14 +3646,14 @@ packages: peerDependencies: webpack: ^5.1.0 - core-js-compat@3.37.0: - resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} + core-js-compat@3.40.0: + resolution: {integrity: sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==} - core-js-pure@3.37.0: - resolution: {integrity: sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ==} + core-js-pure@3.40.0: + resolution: {integrity: sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==} - core-js@3.37.0: - resolution: {integrity: sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==} + core-js@3.40.0: + resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3068,28 +3675,44 @@ packages: typescript: optional: true - cpy@11.0.1: - resolution: {integrity: sha512-VIvf1QNOHnIZ5QT8zWxNJq+YYIpbFhgeMwnVngX+AhhUQd3Rns3x6gcvb0fGpNxZQ0q629mX6+GvDtvbO/Hutg==} + cpy@11.1.0: + resolution: {integrity: sha512-QGHetPSSuprVs+lJmMDcivvrBwTKASzXQ5qxFvRC2RFESjjod71bDvFvhxTjDgkNjrrb72AI6JPjfYwxrIy33A==} engines: {node: '>=18'} - cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} engines: {node: '>=4.8'} - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} + crypto-random-string@5.0.0: + resolution: {integrity: sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==} + engines: {node: '>=14.16'} + + css-blank-pseudo@7.0.1: + resolution: {integrity: sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + css-declaration-sorter@7.2.0: resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.0.9 + css-has-pseudo@7.0.2: + resolution: {integrity: sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + css-loader@6.11.0: resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} engines: {node: '>= 12.13.0'} @@ -3127,6 +3750,12 @@ packages: lightningcss: optional: true + css-prefers-color-scheme@10.0.0: + resolution: {integrity: sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -3145,6 +3774,9 @@ packages: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} + cssdb@8.2.3: + resolution: {integrity: sha512-9BDG5XmJrJQQnJ51VFxXCAtpZ5ebDlAREmO8sxMOVU0aSxN/gocbctjIG5LMh3WBUq+xTlb/jw2LoljBEqraTA==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -3181,16 +3813,16 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} debounce-fn@5.1.2: @@ -3217,6 +3849,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} @@ -3239,6 +3880,14 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@3.0.0: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} + engines: {node: '>=12'} + + default-browser@4.0.0: + resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} + engines: {node: '>=14.16'} + default-gateway@6.0.3: resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} engines: {node: '>= 10'} @@ -3255,6 +3904,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -3299,17 +3952,14 @@ packages: engines: {node: '>= 4.2.1'} hasBin: true - detect-port@1.5.1: - resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} hasBin: true devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} - engines: {node: '>=0.3.1'} - diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} @@ -3355,8 +4005,8 @@ packages: domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -3369,6 +4019,14 @@ packages: resolution: {integrity: sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -3382,11 +4040,11 @@ packages: resolution: {integrity: sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA==} engines: {node: '>=6'} - electron-to-chromium@1.4.757: - resolution: {integrity: sha512-jftDaCknYSSt/+KKeXzH3LX5E2CvRLm75P3Hj+J/dv3CL0qUYcOt13d5FN1NiL5IJbbhzHrb3BomeG2tkSlZmw==} + electron-to-chromium@1.5.84: + resolution: {integrity: sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==} - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3401,22 +4059,26 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} - emoticon@4.0.1: - resolution: {integrity: sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==} + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - enhanced-resolve@5.16.0: - resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} + enhanced-resolve@5.18.0: + resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} engines: {node: '>=10.13.0'} - entail@2.1.2: - resolution: {integrity: sha512-/icW51VHeJo5j6z6/80vO6R7zAdvHDODHYcc2jItrhRvP/zfTlm2b+xcEkp/Vt3UI6R5651Stw0AGpE1Gzkm6Q==} + entail@2.2.1: + resolution: {integrity: sha512-CWOa+T3NffvmAJ8LULbeFa0A+jLj6klRGyUKlUo4l/fH7nXR8EkV7f8+z99p+mEFO6+43vvOB3YxC1wlt5nthA==} hasBin: true entities@2.2.0: @@ -3430,39 +4092,49 @@ packages: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + err-code@3.0.1: resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} engines: {node: '>= 0.4'} - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.5.2: - resolution: {integrity: sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==} + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} - es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild-plugin-wasm@1.1.0: resolution: {integrity: sha512-0bQ6+1tUbySSnxzn5jnXHMDvYnT0cN/Wd4Syk8g/sqAIJUg7buTIi22svS3Qz6ssx895NT+TgLPb33xi1OkZig==} engines: {node: '>=0.10.0'} @@ -3472,8 +4144,13 @@ packages: engines: {node: '>=12'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-goat@4.0.0: @@ -3513,9 +4190,10 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -3527,8 +4205,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -3552,11 +4230,14 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + estree-util-to-js@2.0.0: resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - estree-util-value-to-estree@3.1.1: - resolution: {integrity: sha512-5mvUrF2suuv5f5cGDnDphIy4/gW86z82kl5qG6mM9z04SEQI4FB5Apmaw/TGEf3l55nLtMs5s51dmhUzvAHQCA==} + estree-util-value-to-estree@3.2.1: + resolution: {integrity: sha512-Vt2UOjyPbNQQgT5eJh+K5aATti0OjCIAGc9SgMdOFYbohuifsWclR74l0iZTJwePMgWYdX1hlVS+dedH9XV8kw==} estree-util-visit@2.0.0: resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} @@ -3616,8 +4297,8 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} - express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} extend-shallow@2.0.1: @@ -3627,14 +4308,18 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -3643,11 +4328,11 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-url-parser@1.1.3: - resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fastq@1.18.0: + resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} @@ -3663,6 +4348,10 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3673,16 +4362,20 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 + files-from-path@1.1.1: + resolution: {integrity: sha512-M2JDH/0gHqIsdwTnp8IBMWEYUUiHe9ei0ZMTXLxqKFcGxJF4Ki+nicw2k8HP5KGEzPLTyJ81XwLmP8l8rKa6qg==} + engines: {node: '>=18'} + filesize@8.0.7: resolution: {integrity: sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==} engines: {node: '>= 0.4.0'} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} find-cache-dir@4.0.0: @@ -3713,11 +4406,11 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + flatted@3.3.2: + resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -3732,8 +4425,8 @@ packages: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} fork-ts-checker-webpack-plugin@6.5.3: @@ -3772,8 +4465,8 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} fs-extra@9.1.0: @@ -3794,8 +4487,8 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} functions-have-names@1.2.3: @@ -3809,8 +4502,12 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} engines: {node: '>= 0.4'} get-iterator@1.0.2: @@ -3819,6 +4516,14 @@ packages: get-own-enumerable-property-symbols@3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stdin@4.0.1: + resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} + engines: {node: '>=0.10.0'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -3827,8 +4532,8 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} github-slugger@1.5.0: @@ -3858,6 +4563,10 @@ packages: engines: {node: '>=12'} deprecated: Glob versions prior to v9 are no longer supported + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} @@ -3902,12 +4611,13 @@ packages: resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - globby@14.0.1: - resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==} + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} engines: {node: '>=18'} - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} got@12.6.1: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} @@ -3941,8 +4651,14 @@ packages: engines: {node: '>=0.4.7'} hasBin: true - has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-ansi@1.0.3: + resolution: {integrity: sha512-XwLzIec2hoj/LW9F3nCcQpEwZ5fDJ1LOc6SAgc0pz79CGiY9zmZhIkbf7OnK+tC36UhpQBa03HPt13QavGoF6Q==} + engines: {node: '>=0.10.0'} + hasBin: true + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -3955,12 +4671,12 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} has-tostringtag@1.0.2: @@ -3975,20 +4691,20 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hast-util-from-parse5@8.0.1: - resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} + hast-util-from-parse5@8.0.2: + resolution: {integrity: sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A==} hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - hast-util-raw@9.0.3: - resolution: {integrity: sha512-ICWvVOF2fq4+7CMmtCPD5CM4QKjPbHpPotE6+8tDooV0ZuyJVUzHsrNX+O5NaRbieTf0F7FfeBOMAwi6Td0+yQ==} + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} - hast-util-to-estree@3.1.0: - resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} + hast-util-to-estree@3.1.1: + resolution: {integrity: sha512-IWtwwmPskfSmma9RpzCappDUitC8t5jhAynHhc1m2+5trOgsrp7txscUSavc5Ic8PATyAjfrCK1wgtxh2cICVQ==} - hast-util-to-jsx-runtime@2.3.0: - resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} + hast-util-to-jsx-runtime@2.3.2: + resolution: {integrity: sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==} hast-util-to-parse5@8.0.0: resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} @@ -3996,13 +4712,16 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - hastscript@8.0.0: - resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + hastscript@9.0.0: + resolution: {integrity: sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==} he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + history@4.10.1: resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} @@ -4042,8 +4761,8 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - html-webpack-plugin@5.6.0: - resolution: {integrity: sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==} + html-webpack-plugin@5.6.3: + resolution: {integrity: sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==} engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -4074,11 +4793,11 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} - http-parser-js@0.5.8: - resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + http-parser-js@0.5.9: + resolution: {integrity: sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==} - http-proxy-middleware@2.0.6: - resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + http-proxy-middleware@2.0.7: + resolution: {integrity: sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/express': ^4.17.13 @@ -4127,12 +4846,12 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - image-size@1.1.1: - resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==} + image-size@1.2.0: + resolution: {integrity: sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w==} engines: {node: '>=16.x'} hasBin: true @@ -4155,12 +4874,8 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - infima@0.2.0-alpha.43: - resolution: {integrity: sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==} + infima@0.2.0-alpha.45: + resolution: {integrity: sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==} engines: {node: '>=12'} inflight@1.0.6: @@ -4180,11 +4895,12 @@ packages: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} - inline-style-parser@0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inline-style-parser@0.2.3: - resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} interface-blockstore@4.0.1: resolution: {integrity: sha512-ROWKGJls7vLeFaQtI3hZVCJOkUoZ05xAi2t2qysM4d7dwVKrfm5jUOqWh8JgLL7Iup3XqJ0mKXXZuwJ3s03RSw==} @@ -4194,8 +4910,8 @@ packages: resolution: {integrity: sha512-OjHUuGXbH4eXSBx1TF1tTySvjLldPLzRSYYXJwrEQI+XfH5JWYZofr0gVMV4F8XTwC+4V7jomDYkvGRmDSRKqQ==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} interpret@1.4.0: @@ -4231,26 +4947,31 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} engines: {node: '>= 0.4'} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-async-function@2.1.0: + resolution: {integrity: sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.1: + resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} engines: {node: '>= 0.4'} is-builtin-module@3.2.1: @@ -4265,15 +4986,16 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} - is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} - is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} is-decimal@2.0.1: @@ -4284,6 +5006,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-electron@2.2.2: resolution: {integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==} @@ -4295,6 +5022,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -4303,8 +5034,8 @@ packages: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} - is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -4314,28 +5045,42 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ci@1.0.0: + resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==} + engines: {node: '>=18'} + hasBin: true + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-installed-globally@0.4.0: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} - is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} is-npm@6.0.0: resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -4358,6 +5103,10 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -4374,11 +5123,8 @@ packages: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} - is-reference@3.0.2: - resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} - - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} is-regexp@1.0.0: @@ -4389,8 +5135,12 @@ packages: resolution: {integrity: sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==} engines: {node: '>=6'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} is-stream@2.0.1: @@ -4401,19 +5151,19 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} is-subset@0.1.1: resolution: {integrity: sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} is-typedarray@1.0.0: @@ -4427,8 +5177,17 @@ packages: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} - is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.0: + resolution: {integrity: sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} @@ -4504,8 +5263,8 @@ packages: resolution: {integrity: sha512-ItoBy3dPlNKnhjHR8e7nfabfZzH4Jy2OMPvayYH3XHy4YNqSVKmWTIxhz7KX4UMBsLChlIJZ+5j6csJgrYGQtw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - it-parallel@3.0.7: - resolution: {integrity: sha512-aIIc2t8knfER/mQu4uEHaAYZrnj/2Tdp+Vj6BA94Gi7xghx1kblvpyrLkCYO9K+eDyPS1cE3Vfhh9a20MEmzXA==} + it-parallel@3.0.8: + resolution: {integrity: sha512-URLhs6eG4Hdr4OdvgBBPDzOjBeSSmI+Kqex2rv/aAyYClME26RYHirLVhZsZP5M+ZP6M34iRlXk8Wlqtezuqpg==} it-pipe@2.0.5: resolution: {integrity: sha512-y85nW1N6zoiTnkidr2EAyC+ZVzc7Mwt2p+xt2a2ooG1ThFakSpNw1Kxm+7F13Aivru96brJhjQVRQNU+w0yozw==} @@ -4540,12 +5299,12 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - joi@17.13.1: - resolution: {integrity: sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==} + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4562,13 +5321,14 @@ packages: resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} engines: {node: '>=12.0.0'} - jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: @@ -4597,8 +5357,8 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -4625,12 +5385,20 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + ky@1.7.4: + resolution: {integrity: sha512-zYEr/gh7uLW2l4su11bmQ2M9xLgQLjyvx58UyNM/6nuqyWFHPX5ktMjvpev3F8QWdjSsHUpnWew4PBCswBNuMQ==} + engines: {node: '>=18'} + latest-version@7.0.0: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} - launch-editor@2.6.1: - resolution: {integrity: sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==} + latest-version@9.0.0: + resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==} + engines: {node: '>=18'} + + launch-editor@2.9.1: + resolution: {integrity: sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==} leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -4644,8 +5412,8 @@ packages: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} - lilconfig@3.1.1: - resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} lines-and-columns@1.2.4: @@ -4677,8 +5445,8 @@ packages: resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} engines: {node: '>=8.9.0'} - loader-utils@3.2.1: - resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==} + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} locate-path@3.0.0: @@ -4723,8 +5491,8 @@ packages: resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - long@5.2.3: - resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + long@5.2.4: + resolution: {integrity: sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==} longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -4746,15 +5514,11 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -4764,14 +5528,17 @@ packages: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} - markdown-table@3.0.3: - resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - marked-terminal@6.2.0: - resolution: {integrity: sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==} + marked-terminal@7.2.1: + resolution: {integrity: sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==} engines: {node: '>=16.0.0'} peerDependencies: - marked: '>=1 <12' + marked: '>=1 <15' marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} @@ -4787,20 +5554,24 @@ packages: resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==} engines: {node: '>=6'} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-directive@3.0.0: resolution: {integrity: sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==} - mdast-util-find-and-replace@3.0.1: - resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - mdast-util-from-markdown@2.0.0: - resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} mdast-util-frontmatter@2.0.1: resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} - mdast-util-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} mdast-util-gfm-footnote@2.0.0: resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} @@ -4817,11 +5588,11 @@ packages: mdast-util-gfm@3.0.0: resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} - mdast-util-mdx-expression@2.0.0: - resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - mdast-util-mdx-jsx@3.1.2: - resolution: {integrity: sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==} + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} mdast-util-mdx@3.0.0: resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} @@ -4832,11 +5603,11 @@ packages: mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - mdast-util-to-hast@13.1.0: - resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} - mdast-util-to-markdown@2.1.0: - resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} @@ -4859,8 +5630,8 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} merge-options@3.0.4: resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} @@ -4880,32 +5651,32 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - micromark-core-commonmark@2.0.1: - resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + micromark-core-commonmark@2.0.2: + resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} - micromark-extension-directive@3.0.0: - resolution: {integrity: sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==} + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} micromark-extension-frontmatter@2.0.0: resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} - micromark-extension-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - micromark-extension-gfm-footnote@2.0.0: - resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - micromark-extension-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - micromark-extension-gfm-table@2.0.0: - resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} micromark-extension-gfm-tagfilter@2.0.0: resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - micromark-extension-gfm-task-list-item@2.0.1: - resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} @@ -4913,8 +5684,8 @@ packages: micromark-extension-mdx-expression@3.0.0: resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} - micromark-extension-mdx-jsx@3.0.0: - resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} + micromark-extension-mdx-jsx@3.0.1: + resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==} micromark-extension-mdx-md@2.0.0: resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} @@ -4925,88 +5696,92 @@ packages: micromark-extension-mdxjs@3.0.0: resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} - micromark-factory-destination@2.0.0: - resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} - micromark-factory-label@2.0.0: - resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - micromark-factory-mdx-expression@2.0.1: - resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} + micromark-factory-mdx-expression@2.0.2: + resolution: {integrity: sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==} micromark-factory-space@1.1.0: resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} - micromark-factory-space@2.0.0: - resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} - micromark-factory-title@2.0.0: - resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} - micromark-factory-whitespace@2.0.0: - resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} micromark-util-character@1.2.0: resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} - micromark-util-character@2.1.0: - resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - micromark-util-chunked@2.0.0: - resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} - micromark-util-classify-character@2.0.0: - resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} - micromark-util-combine-extensions@2.0.0: - resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} - micromark-util-decode-numeric-character-reference@2.0.1: - resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} - micromark-util-decode-string@2.0.0: - resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} - micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} micromark-util-events-to-acorn@2.0.2: resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} - micromark-util-html-tag-name@2.0.0: - resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} - micromark-util-normalize-identifier@2.0.0: - resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} - micromark-util-resolve-all@2.0.0: - resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} - micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - micromark-util-subtokenize@2.0.1: - resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + micromark-util-subtokenize@2.0.4: + resolution: {integrity: sha512-N6hXjrin2GTJDe3MVjf5FuXpm12PGm80BrUAeub9XFXca8JZbP+oIwY4LJSVwFUCL1IPm/WwSVUN7goFHmSGGQ==} micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} - micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} micromark-util-types@1.1.0: resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} - micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + micromark-util-types@2.0.1: + resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} - micromark@4.0.0: - resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + micromark@4.0.1: + resolution: {integrity: sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==} micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.33.0: resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} engines: {node: '>= 0.6'} @@ -5015,6 +5790,10 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.53.0: + resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} + engines: {node: '>= 0.6'} + mime-types@2.1.18: resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} engines: {node: '>= 0.6'} @@ -5044,8 +5823,8 @@ packages: resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - mini-css-extract-plugin@2.9.0: - resolution: {integrity: sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==} + mini-css-extract-plugin@2.9.2: + resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -5056,8 +5835,8 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} minimatch@7.4.6: @@ -5068,8 +5847,8 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -5079,8 +5858,8 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - mocha@10.4.0: - resolution: {integrity: sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==} + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} engines: {node: '>= 14.0.0'} hasBin: true @@ -5113,11 +5892,8 @@ packages: resolution: {integrity: sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} - multiformats@13.1.0: - resolution: {integrity: sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==} - - multiformats@13.3.0: - resolution: {integrity: sha512-CBiqvsufgmpo01VT5ze94O+uc+Pbf6f/sThlvWss0sBZmAOu6GQn5usrYV2sf2mr17FWYc0rO8c/CNe2T90QAA==} + multiformats@13.3.1: + resolution: {integrity: sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g==} multimatch@5.0.0: resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} @@ -5127,13 +5903,20 @@ packages: resolution: {integrity: sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==} engines: {node: '>=8.0.0'} - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.0.7: - resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + nanoid@5.0.9: + resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==} engines: {node: ^18 || >=20} hasBin: true @@ -5149,6 +5932,10 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -5161,8 +5948,8 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-emoji@2.1.3: - resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} engines: {node: '>=18'} node-fetch@2.7.0: @@ -5178,8 +5965,8 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -5215,12 +6002,19 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + null-loader@4.0.1: + resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} object-is@1.1.6: resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} @@ -5230,8 +6024,8 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} obuf@1.1.2: @@ -5263,6 +6057,10 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + open@9.1.0: + resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} + engines: {node: '>=14.16'} + opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true @@ -5275,6 +6073,14 @@ packages: resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} engines: {node: '>=16'} + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -5294,9 +6100,9 @@ packages: p-fifo@1.0.0: resolution: {integrity: sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==} - p-filter@3.0.0: - resolution: {integrity: sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-filter@4.1.0: + resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} + engines: {node: '>=18'} p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} @@ -5326,14 +6132,14 @@ packages: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} - p-map@5.5.0: - resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} - engines: {node: '>=12'} - p-map@6.0.0: resolution: {integrity: sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==} engines: {node: '>=16'} + p-map@7.0.3: + resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + engines: {node: '>=18'} + p-queue@7.4.1: resolution: {integrity: sha512-vRpMXmIkYF2/1hLBKisKeVYJZ8S2tZ0zEAmIJgdVKP2nq0nh4qCdf8bgw+ZgKrkh71AOCaqzwbJJk1WtdcF3VA==} engines: {node: '>=12'} @@ -5350,8 +6156,8 @@ packages: resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} engines: {node: '>=12'} - p-timeout@6.1.2: - resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} p-try@2.2.0: @@ -5362,8 +6168,12 @@ packages: resolution: {integrity: sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==} engines: {node: '>=12'} - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-json@10.0.1: + resolution: {integrity: sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==} + engines: {node: '>=18'} package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} @@ -5376,8 +6186,8 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-entities@4.0.1: - resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} @@ -5394,11 +6204,20 @@ packages: resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} engines: {node: '>=0.10.0'} - parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} @@ -5448,17 +6267,17 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - path-to-regexp@1.8.0: - resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} - path-to-regexp@2.2.1: - resolution: {integrity: sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==} + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -5472,11 +6291,8 @@ packages: resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} engines: {node: '>=12'} - periscopic@3.1.0: - resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -5524,11 +6340,41 @@ packages: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + postcss-attribute-case-insensitive@7.0.1: + resolution: {integrity: sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-calc@9.0.1: resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: - postcss: ^8.2.2 + postcss: ^8.2.2 + + postcss-clamp@4.1.0: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + + postcss-color-functional-notation@7.0.7: + resolution: {integrity: sha512-EZvAHsvyASX63vXnyXOIynkxhaHRSsdb7z6yiXKIovGXAolW4cMZ3qoh7k3VdTsLBS6VGdksGfIo3r6+waLoOw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-hex-alpha@10.0.0: + resolution: {integrity: sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-rebeccapurple@10.0.0: + resolution: {integrity: sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 postcss-colormin@6.1.0: resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} @@ -5542,6 +6388,30 @@ packages: peerDependencies: postcss: ^8.4.31 + postcss-custom-media@11.0.5: + resolution: {integrity: sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-properties@14.0.4: + resolution: {integrity: sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-selectors@8.0.4: + resolution: {integrity: sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-dir-pseudo-class@9.0.1: + resolution: {integrity: sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-discard-comments@6.0.2: resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} engines: {node: ^14 || ^16 || >=18.0} @@ -5572,6 +6442,47 @@ packages: peerDependencies: postcss: ^8.4.31 + postcss-double-position-gradients@6.0.0: + resolution: {integrity: sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-visible@10.0.1: + resolution: {integrity: sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-within@9.0.1: + resolution: {integrity: sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-font-variant@5.0.0: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + + postcss-gap-properties@6.0.0: + resolution: {integrity: sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-image-set-function@7.0.0: + resolution: {integrity: sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-lab-function@7.0.7: + resolution: {integrity: sha512-+ONj2bpOQfsCKZE2T9VGMyVVdGcGUpr7u3SVfvkJlvhTRmDCfY25k4Jc8fubB9DclAPR4+w8uVtDZmdRgdAHig==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-loader@7.3.4: resolution: {integrity: sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==} engines: {node: '>= 14.15.0'} @@ -5579,6 +6490,12 @@ packages: postcss: ^7.0.0 || ^8.0.1 webpack: ^5.0.0 + postcss-logical@8.0.0: + resolution: {integrity: sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-merge-idents@6.0.3: resolution: {integrity: sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==} engines: {node: ^14 || ^16 || >=18.0} @@ -5627,14 +6544,14 @@ packages: peerDependencies: postcss: ^8.1.0 - postcss-modules-local-by-default@4.0.5: - resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 - postcss-modules-scope@3.2.0: - resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 @@ -5645,6 +6562,12 @@ packages: peerDependencies: postcss: ^8.1.0 + postcss-nesting@13.0.1: + resolution: {integrity: sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-normalize-charset@6.0.2: resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} engines: {node: ^14 || ^16 || >=18.0} @@ -5699,12 +6622,47 @@ packages: peerDependencies: postcss: ^8.4.31 + postcss-opacity-percentage@3.0.0: + resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-ordered-values@6.0.2: resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 + postcss-overflow-shorthand@6.0.0: + resolution: {integrity: sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-page-break@3.0.4: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + + postcss-place@10.0.0: + resolution: {integrity: sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-preset-env@10.1.3: + resolution: {integrity: sha512-9qzVhcMFU/MnwYHyYpJz4JhGku/4+xEiPTmhn0hj3IxnUYlEF9vbh7OC1KoLAnenS6Fgg43TKNp9xcuMeAi4Zw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-pseudo-class-any-link@10.0.1: + resolution: {integrity: sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + postcss-reduce-idents@6.0.3: resolution: {integrity: sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==} engines: {node: ^14 || ^16 || >=18.0} @@ -5723,8 +6681,23 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + postcss-replace-overflow-wrap@4.0.0: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + + postcss-selector-not@8.0.1: + resolution: {integrity: sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.0.0: + resolution: {integrity: sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==} engines: {node: '>=4'} postcss-sort-media-queries@5.2.0: @@ -5754,8 +6727,8 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + postcss@8.5.1: + resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -5772,6 +6745,11 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + engines: {node: '>=14'} + hasBin: true + pretty-error@4.0.0: resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} @@ -5779,8 +6757,11 @@ packages: resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} engines: {node: '>=4'} - prism-react-renderer@2.3.1: - resolution: {integrity: sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==} + pretty-tree@1.0.0: + resolution: {integrity: sha512-BfBHciLsD6KtzG60Lfz6+FRWAjLvBwembXOzJg8lUqYe5eA7ujWB+9wZgrlN4lskhcgUEuIj8OFkIHwxUyh+tQ==} + + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} peerDependencies: react: '>=16.0.0' @@ -5808,17 +6789,14 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - protobufjs@7.2.6: - resolution: {integrity: sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==} + protobufjs@7.4.0: + resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -5827,8 +6805,8 @@ packages: resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} engines: {node: '>=12.20'} - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -5884,22 +6862,11 @@ packages: react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} - react-helmet-async@1.3.0: - resolution: {integrity: sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==} - peerDependencies: - react: ^16.6.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 - - react-helmet-async@2.0.5: - resolution: {integrity: sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==} - peerDependencies: - react: ^16.6.0 || ^17.0.0 || ^18.0.0 - react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-json-view-lite@1.4.0: - resolution: {integrity: sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==} + react-json-view-lite@1.5.0: + resolution: {integrity: sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==} engines: {node: '>=14'} peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -5956,15 +6923,28 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.0: + resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + recursive-readdir@2.2.3: resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} engines: {node: '>=6.0.0'} - redeyed@2.1.1: - resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} regenerate@1.4.2: @@ -5976,29 +6956,35 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + regexpu-core@6.2.0: + resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} engines: {node: '>=4'} - registry-auth-token@5.0.2: - resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + registry-auth-token@5.0.3: + resolution: {integrity: sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==} engines: {node: '>=14'} registry-url@6.0.1: resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} engines: {node: '>=12'} - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + relateurl@0.2.7: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} @@ -6016,14 +7002,14 @@ packages: remark-gfm@4.0.0: resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} - remark-mdx@3.0.1: - resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} + remark-mdx@3.1.0: + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - remark-rehype@11.1.0: - resolution: {integrity: sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==} + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} @@ -6031,6 +7017,10 @@ packages: renderkid@3.0.0: resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -6066,8 +7056,9 @@ packages: resolve-pathname@3.0.0: resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} hasBin: true responselike@3.0.0: @@ -6086,34 +7077,42 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.3.1: - resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rtl-detect@1.1.2: - resolution: {integrity: sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==} - - rtlcss@4.1.1: - resolution: {integrity: sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==} + rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} engines: {node: '>=12.0.0'} hasBin: true + run-applescript@5.0.0: + resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} + engines: {node: '>=12'} + + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + s-ago@2.2.0: + resolution: {integrity: sha512-t6Q/aFCCJSBf5UUkR/WH0mDHX8EGm2IBQ7nQLobVLsdxOlkryYMbOlwu2D4Cf7jPUp0v1LhfPgvIZNoi9k8lUA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} safe-buffer@5.1.2: @@ -6122,15 +7121,19 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.3.0: - resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -6143,12 +7146,12 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} - schema-utils@4.2.0: - resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} - engines: {node: '>= 12.13.0'} + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} - search-insights@2.13.0: - resolution: {integrity: sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==} + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} @@ -6176,30 +7179,27 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} - serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-handler@6.1.5: - resolution: {integrity: sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==} + serve-handler@6.1.6: + resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} serve-index@1.9.1: resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} engines: {node: '>= 0.8.0'} - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} set-function-length@1.2.2: @@ -6210,6 +7210,10 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} @@ -6239,8 +7243,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.1: - resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} shelljs@0.8.5: resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} @@ -6250,8 +7255,20 @@ packages: shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} signal-exit@3.0.7: @@ -6272,8 +7289,8 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sitemap@7.1.1: - resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==} + sitemap@7.1.2: + resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==} engines: {node: '>=12.0.0', npm: '>=5.6.0'} hasBin: true @@ -6307,8 +7324,8 @@ packages: resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} engines: {node: '>= 6.3.0'} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map-support@0.5.21: @@ -6340,8 +7357,8 @@ packages: spdx-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-license-ids@3.0.17: - resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -6365,8 +7382,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} stdin-discarder@0.1.0: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} @@ -6394,16 +7411,21 @@ packages: resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} engines: {node: '>=16'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.padend@3.1.6: resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} - string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} @@ -6422,6 +7444,11 @@ packages: resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} engines: {node: '>=4'} + strip-ansi@2.0.1: + resolution: {integrity: sha512-2h8q2CP3EeOhDJ+jd932PRMpa3/pOJFGoF22J1U/DNbEK2gSW2DqeF46VjCXsSQXhC+k/l8/gaaRBQKL6hUPfQ==} + engines: {node: '>=0.10.0'} + hasBin: true + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -6457,11 +7484,8 @@ packages: stubborn-fs@1.2.5: resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} - style-to-object@0.4.4: - resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} - - style-to-object@1.0.6: - resolution: {integrity: sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==} + style-to-object@1.0.8: + resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} stylehacks@6.1.1: resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} @@ -6469,6 +7493,11 @@ packages: peerDependencies: postcss: ^8.4.31 + supports-color@1.3.1: + resolution: {integrity: sha512-OHbMkscHFRcNWEcW80fYhCrzAjheSIBwJChpFaBqA6zEz53nxumqi6ukciRb/UA0/v2nDNMk28ce/uBbYRDsng==} + engines: {node: '>=0.8.0'} + hasBin: true + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -6481,8 +7510,8 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + supports-hyperlinks@3.1.0: + resolution: {integrity: sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==} engines: {node: '>=14.18'} supports-preserve-symlinks-flag@1.0.0: @@ -6492,8 +7521,8 @@ packages: svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} - svgo@3.2.0: - resolution: {integrity: sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==} + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} engines: {node: '>=14.0.0'} hasBin: true @@ -6516,8 +7545,8 @@ packages: resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} engines: {node: '>=14.16'} - terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + terser-webpack-plugin@5.3.11: + resolution: {integrity: sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -6532,8 +7561,8 @@ packages: uglify-js: optional: true - terser@5.31.0: - resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==} + terser@5.37.0: + resolution: {integrity: sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==} engines: {node: '>=10'} hasBin: true @@ -6548,6 +7577,13 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} @@ -6557,9 +7593,13 @@ packages: tiny-warning@1.0.3: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + titleize@3.0.0: + resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} + engines: {node: '>=12'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -6586,8 +7626,8 @@ packages: resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==} engines: {node: '>=6'} - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -6595,8 +7635,8 @@ packages: ts-expose-internals-conditionally@1.0.0-empty.0: resolution: {integrity: sha512-F8m9NOF6ZhdOClDVdlM8gj3fDCav4ZIFSs/EI3ksQbAAXVSCN/Jh5OCJDDZWBuBy9psFc6jULGDlPwjMYMhJDw==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -6606,10 +7646,18 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + type-fest@1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} @@ -6622,28 +7670,28 @@ packages: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} - type-fest@4.18.2: - resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==} + type-fest@4.33.0: + resolution: {integrity: sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==} engines: {node: '>=16'} type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} typedarray-to-buffer@3.1.5: @@ -6654,8 +7702,8 @@ packages: peerDependencies: typedoc: '>=0.24.0' - typedoc-plugin-missing-exports@2.2.0: - resolution: {integrity: sha512-2+XR1IcyQ5UwXZVJe9NE6HrLmNufT9i5OwoIuuj79VxuA3eYq+Y6itS9rnNV1D7UeQnUSH8kISYD73gHE5zw+w==} + typedoc-plugin-missing-exports@2.3.0: + resolution: {integrity: sha512-iI9ITNNLlbsLCBBeYDyu0Qqp3GN/9AGyWNKg8bctRXuZEPT7G1L+0+MNWG9MsHcf/BFmNbXL0nQ8mC/tXRicog==} peerDependencies: typedoc: 0.24.x || 0.25.x @@ -6676,8 +7724,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - uglify-js@3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} hasBin: true @@ -6687,17 +7735,18 @@ packages: uint8arrays@4.0.10: resolution: {integrity: sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA==} - uint8arrays@5.0.3: - resolution: {integrity: sha512-6LBuKji28kHjgPJMkQ6GDaBb1lRwIhyOYq6pDGwYMoDPfImE9SkuYENVmR0yu9yGgs2clHUSY9fKDukR+AXfqQ==} + uint8arrays@5.1.0: + resolution: {integrity: sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==} - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} unicode-emoji-modifier-base@1.0.0: @@ -6708,8 +7757,8 @@ packages: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} engines: {node: '>=4'} unicode-property-aliases-ecmascript@2.1.0: @@ -6720,8 +7769,8 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} unique-string@3.0.0: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} @@ -6736,9 +7785,6 @@ packages: unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} @@ -6756,8 +7802,12 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.0.15: - resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==} + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + update-browserslist-db@1.1.2: + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6766,6 +7816,10 @@ packages: resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} engines: {node: '>=14.16'} + update-notifier@7.3.1: + resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} + engines: {node: '>=18'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -6805,8 +7859,8 @@ packages: engines: {node: '>=8'} hasBin: true - v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} validate-npm-package-license@3.0.4: @@ -6826,14 +7880,14 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vfile-location@5.0.2: - resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} @@ -6846,8 +7900,8 @@ packages: engines: {node: '>=0.1.95'} hasBin: true - watchpack@2.4.1: - resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} wbuf@1.7.3: @@ -6894,12 +7948,16 @@ packages: resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} engines: {node: '>=10.0.0'} + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + webpack-sources@3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - webpack@5.91.0: - resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==} + webpack@5.97.1: + resolution: {integrity: sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -6908,9 +7966,9 @@ packages: webpack-cli: optional: true - webpackbar@5.0.2: - resolution: {integrity: sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==} - engines: {node: '>=12'} + webpackbar@6.0.1: + resolution: {integrity: sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==} + engines: {node: '>=14.21.3'} peerDependencies: webpack: 3 || 4 || 5 @@ -6925,14 +7983,23 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - when-exit@2.1.2: - resolution: {integrity: sha512-u9J+toaf3CCxCAzM/484qNAxQE75rFdVgiFEEV8Xps2gzYhf0tx73s1WXDQhkwV17E3MxRMz40m7Ekd2/121Lg==} + when-exit@2.1.4: + resolution: {integrity: sha512-4rnvd3A1t16PWzrBUcSDZqcAmsUIy4minDXT/CZ8F2mVDgd65i4Aalimgz1aQkRGU0iH5eT5+6Rx2TK8o443Pg==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} engines: {node: '>= 0.4'} which@1.3.1: @@ -6948,6 +8015,10 @@ packages: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -6958,8 +8029,12 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} @@ -6969,14 +8044,18 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - ws@7.5.9: - resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} engines: {node: '>=8.3.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6987,8 +8066,8 @@ packages: utf-8-validate: optional: true - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -7014,9 +8093,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -7025,10 +8101,6 @@ packages: resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} engines: {node: '>= 14'} - yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -7053,8 +8125,8 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} zwitch@2.0.4: @@ -7062,1034 +8134,1283 @@ packages: snapshots: - '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0)': + '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0) - '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) - search-insights: 2.13.0 + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0) + search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)': dependencies: - '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) - '@algolia/client-search': 4.23.3 - algoliasearch: 4.23.3 + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0) + '@algolia/client-search': 5.20.0 + algoliasearch: 5.20.0 - '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)': dependencies: - '@algolia/client-search': 4.23.3 - algoliasearch: 4.23.3 + '@algolia/client-search': 5.20.0 + algoliasearch: 5.20.0 - '@algolia/cache-browser-local-storage@4.23.3': + '@algolia/client-abtesting@5.20.0': dependencies: - '@algolia/cache-common': 4.23.3 - - '@algolia/cache-common@4.23.3': {} + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/cache-in-memory@4.23.3': + '@algolia/client-analytics@5.20.0': dependencies: - '@algolia/cache-common': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/client-account@4.23.3': - dependencies: - '@algolia/client-common': 4.23.3 - '@algolia/client-search': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common@5.20.0': {} - '@algolia/client-analytics@4.23.3': + '@algolia/client-insights@5.20.0': dependencies: - '@algolia/client-common': 4.23.3 - '@algolia/client-search': 4.23.3 - '@algolia/requester-common': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/client-common@4.23.3': + '@algolia/client-personalization@5.20.0': dependencies: - '@algolia/requester-common': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/client-personalization@4.23.3': + '@algolia/client-query-suggestions@5.20.0': dependencies: - '@algolia/client-common': 4.23.3 - '@algolia/requester-common': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/client-search@4.23.3': + '@algolia/client-search@5.20.0': dependencies: - '@algolia/client-common': 4.23.3 - '@algolia/requester-common': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 '@algolia/events@4.0.1': {} - '@algolia/logger-common@4.23.3': {} - - '@algolia/logger-console@4.23.3': + '@algolia/ingestion@1.20.0': dependencies: - '@algolia/logger-common': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/recommend@4.23.3': + '@algolia/monitoring@1.20.0': dependencies: - '@algolia/cache-browser-local-storage': 4.23.3 - '@algolia/cache-common': 4.23.3 - '@algolia/cache-in-memory': 4.23.3 - '@algolia/client-common': 4.23.3 - '@algolia/client-search': 4.23.3 - '@algolia/logger-common': 4.23.3 - '@algolia/logger-console': 4.23.3 - '@algolia/requester-browser-xhr': 4.23.3 - '@algolia/requester-common': 4.23.3 - '@algolia/requester-node-http': 4.23.3 - '@algolia/transporter': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/requester-browser-xhr@4.23.3': + '@algolia/recommend@5.20.0': dependencies: - '@algolia/requester-common': 4.23.3 + '@algolia/client-common': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 - '@algolia/requester-common@4.23.3': {} + '@algolia/requester-browser-xhr@5.20.0': + dependencies: + '@algolia/client-common': 5.20.0 - '@algolia/requester-node-http@4.23.3': + '@algolia/requester-fetch@5.20.0': dependencies: - '@algolia/requester-common': 4.23.3 + '@algolia/client-common': 5.20.0 - '@algolia/transporter@4.23.3': + '@algolia/requester-node-http@5.20.0': dependencies: - '@algolia/cache-common': 4.23.3 - '@algolia/logger-common': 4.23.3 - '@algolia/requester-common': 4.23.3 + '@algolia/client-common': 5.20.0 '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 '@andrewbranch/untar.js@1.0.3': {} - '@arethetypeswrong/cli@0.15.3': + '@arethetypeswrong/cli@0.15.4': dependencies: '@arethetypeswrong/core': 0.15.1 chalk: 4.1.2 - cli-table3: 0.6.4 + cli-table3: 0.6.5 commander: 10.0.1 marked: 9.1.6 - marked-terminal: 6.2.0(marked@9.1.6) - semver: 7.6.0 + marked-terminal: 7.2.1(marked@9.1.6) + semver: 7.6.3 '@arethetypeswrong/core@0.15.1': dependencies: '@andrewbranch/untar.js': 1.0.3 fflate: 0.8.2 - semver: 7.6.0 + semver: 7.6.3 ts-expose-internals-conditionally: 1.0.0-empty.0 typescript: 5.3.3 validate-npm-package-name: 5.0.1 '@arr/every@1.0.1': {} - '@babel/code-frame@7.24.2': + '@babel/code-frame@7.26.2': dependencies: - '@babel/highlight': 7.24.5 - picocolors: 1.0.0 + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/compat-data@7.24.4': {} + '@babel/compat-data@7.26.5': {} - '@babel/core@7.24.5': + '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helpers': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.5 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.5 + '@babel/template': 7.25.9 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.24.5': + '@babel/generator@7.26.5': dependencies: - '@babel/types': 7.24.5 - '@jridgewell/gen-mapping': 0.3.5 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 + '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - - '@babel/helper-annotate-as-pure@7.22.5': - dependencies: - '@babel/types': 7.24.5 + jsesc: 3.1.0 - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': + '@babel/helper-annotate-as-pure@7.25.9': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.26.5 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.26.5': dependencies: - '@babel/compat-data': 7.24.4 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.23.0 + '@babel/compat-data': 7.26.5 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/traverse': 7.26.5 semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.5)': + '@babel/helper-create-regexp-features-plugin@7.26.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.3.2 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + regexpu-core: 6.2.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.5)': + '@babel/helper-define-polyfill-provider@0.6.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - debug: 4.3.4(supports-color@8.1.1) + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + debug: 4.4.0(supports-color@8.1.1) lodash.debounce: 4.0.8 - resolve: 1.22.8 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.25.9': + dependencies: + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.25.9': + dependencies: + '@babel/types': 7.26.5 + + '@babel/helper-plugin-utils@7.26.5': {} + + '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-wrap-function': 7.25.9 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + dependencies: + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helper-wrap-function@7.25.9': + dependencies: + '@babel/template': 7.25.9 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.26.0': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.26.5 + + '@babel/parser@7.26.5': + dependencies: + '@babel/types': 7.26.5 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-async-generator-functions@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) + '@babel/traverse': 7.26.5 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/helper-environment-visitor@7.22.20': {} + '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/template': 7.25.9 + + '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-function-name@7.23.0': + '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-hoist-variables@7.22.5': + '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-member-expression-to-functions@7.24.5': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-module-imports@7.24.3': + '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)': + '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-simple-access': 7.24.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-optimise-call-expression@7.22.5': + '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-plugin-utils@7.24.5': {} + '@babel/plugin-transform-for-of@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color - '@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.5)': + '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-simple-access@7.24.5': + '@babel/plugin-transform-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-split-export-declaration@7.24.5': + '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 - - '@babel/helper-string-parser@7.24.1': {} - - '@babel/helper-validator-identifier@7.24.5': {} + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-option@7.23.5': {} + '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/helper-wrap-function@7.24.5': + '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.26.0)': dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/helpers@7.24.5': + '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color - '@babel/highlight@7.24.5': + '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/helper-validator-identifier': 7.24.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.0.0 + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/parser@7.24.5': + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.5(@babel/core@7.24.5)': + '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-nullish-coalescing-operator@7.26.6(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.24.5(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.5)': + '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.5)': + '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.5)': + '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.5)': + '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.5)': + '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/types': 7.26.5 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.5)': + '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + regenerator-transform: 0.15.2 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.5)': + '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-runtime@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 + babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.5)': + '@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.5)': + '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-template-literals@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.5)': + '@babel/plugin-transform-typeof-symbol@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-typescript@7.26.5(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/preset-env@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/compat-data': 7.26.5 + '@babel/core': 7.26.0 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.0) + '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.26.0) + '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-async-generator-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoped-functions': 7.26.5(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-dynamic-import': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-exponentiation-operator': 7.26.3(@babel/core@7.26.0) + '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-for-of': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-json-strings': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-logical-assignment-operators': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) + '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.26.6(@babel/core@7.26.0) + '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-optional-catch-binding': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-private-property-in-object': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-regenerator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-regexp-modifiers': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-template-literals': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-typeof-symbol': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-property-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.26.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.26.0) + babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) + core-js-compat: 3.40.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.5)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.5) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/types': 7.26.5 + esutils: 2.0.3 - '@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.5)': + '@babel/preset-react@7.26.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.5)': + '@babel/preset-typescript@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) + '@babel/plugin-transform-typescript': 7.26.5(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-block-scoping@7.24.5(@babel/core@7.24.5)': + '@babel/runtime-corejs3@7.26.0': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + core-js-pure: 3.40.0 + regenerator-runtime: 0.14.1 - '@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.5)': + '@babel/runtime@7.26.0': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + regenerator-runtime: 0.14.1 - '@babel/plugin-transform-class-static-block@7.24.4(@babel/core@7.24.5)': + '@babel/template@7.25.9': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.5) + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 - '@babel/plugin-transform-classes@7.24.5(@babel/core@7.24.5)': + '@babel/traverse@7.26.5': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) - '@babel/helper-split-export-declaration': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.5 + '@babel/parser': 7.26.5 + '@babel/template': 7.25.9 + '@babel/types': 7.26.5 + debug: 4.4.0(supports-color@8.1.1) globals: 11.12.0 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.5)': + '@babel/types@7.26.5': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/template': 7.24.0 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 - '@babel/plugin-transform-destructuring@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@bcoe/v8-coverage@0.2.3': {} - '@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@bcoe/v8-coverage@1.0.2': {} - '@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@colors/colors@1.5.0': + optional: true - '@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.5)': + '@csstools/cascade-layer-name-parser@2.0.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/color-helpers@5.0.1': {} - '@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.5)': + '@csstools/css-calc@2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.5) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.5)': + '@csstools/css-color-parser@3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@csstools/color-helpers': 5.0.1 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.5)': + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-tokenizer': 3.0.3 - '@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.5) + '@csstools/css-tokenizer@3.0.3': {} - '@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.5)': + '@csstools/media-query-list-parser@4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-cascade-layers@5.0.1(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.5) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.0.0) + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 - '@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-color-function@4.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-color-mix-function@3.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-content-alt-text@2.0.4(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-simple-access': 7.24.5 + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-exponential-functions@2.0.6(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.5)': + '@csstools/postcss-gamut-mapping@2.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-gradients-interpolation-method@5.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-hwb-function@4.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-ic-unit@4.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.5) + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-object-rest-spread@7.24.5(@babel/core@7.24.5)': + '@csstools/postcss-initial@2.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-transform-parameters': 7.24.5(@babel/core@7.24.5) + postcss: 8.5.1 - '@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-is-pseudo-class@5.0.1(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.0.0) + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 - '@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-light-dark-function@2.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.5) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-optional-chaining@7.24.5(@babel/core@7.24.5)': + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) + postcss: 8.5.1 - '@babel/plugin-transform-parameters@7.24.5(@babel/core@7.24.5)': + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + postcss: 8.5.1 - '@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + postcss: 8.5.1 - '@babel/plugin-transform-private-property-in-object@7.24.5(@babel/core@7.24.5)': + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.5) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-logical-viewport-units@3.0.3(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-tokenizer': 3.0.3 + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-react-constant-elements@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-media-minmax@2.0.6(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + postcss: 8.5.1 - '@babel/plugin-transform-react-display-name@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.4(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + postcss: 8.5.1 - '@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.24.5)': + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.5) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.5)': + '@csstools/postcss-normalize-display-values@4.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) - '@babel/types': 7.24.5 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-react-pure-annotations@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-oklab-function@4.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-progressive-custom-properties@4.0.0(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - regenerator-transform: 0.15.2 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-random-function@1.0.2(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/plugin-transform-runtime@7.24.3(@babel/core@7.24.5)': + '@csstools/postcss-relative-color-syntax@3.0.7(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.5 - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.5) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.5) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.5) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - '@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - - '@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-typeof-symbol@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) - - '@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/preset-env@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/compat-data': 7.24.4 - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.5) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.5) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.5) - '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-async-generator-functions': 7.24.3(@babel/core@7.24.5) - '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-block-scoping': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-class-static-block': 7.24.4(@babel/core@7.24.5) - '@babel/plugin-transform-classes': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-destructuring': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.5) - '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-object-rest-spread': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-optional-chaining': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-parameters': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-private-property-in-object': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-typeof-symbol': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.24.5) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.5) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.5) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.5) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.5)': + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/types': 7.24.5 - esutils: 2.0.3 + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 - '@babel/preset-react@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-sign-functions@1.1.1(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-transform-react-display-name': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.5) - '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.24.5) - '@babel/plugin-transform-react-pure-annotations': 7.24.1(@babel/core@7.24.5) + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/preset-typescript@7.24.1(@babel/core@7.24.5)': + '@csstools/postcss-stepped-value-functions@4.0.6(postcss@8.5.1)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.24.5) - - '@babel/regjsgen@0.8.0': {} + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/runtime-corejs3@7.24.5': + '@csstools/postcss-text-decoration-shorthand@4.0.1(postcss@8.5.1)': dependencies: - core-js-pure: 3.37.0 - regenerator-runtime: 0.14.1 + '@csstools/color-helpers': 5.0.1 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - '@babel/runtime@7.24.5': + '@csstools/postcss-trigonometric-functions@4.0.6(postcss@8.5.1)': dependencies: - regenerator-runtime: 0.14.1 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 - '@babel/template@7.24.0': + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.1)': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + postcss: 8.5.1 - '@babel/traverse@7.24.5': + '@csstools/selector-resolve-nested@3.0.0(postcss-selector-parser@7.0.0)': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + postcss-selector-parser: 7.0.0 - '@babel/types@7.24.5': + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.0.0)': dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.24.5 - to-fast-properties: 2.0.0 + postcss-selector-parser: 7.0.0 - '@bcoe/v8-coverage@0.2.3': {} - - '@colors/colors@1.5.0': - optional: true + '@csstools/utilities@2.0.0(postcss@8.5.1)': + dependencies: + postcss: 8.5.1 '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/css@3.6.0': {} + '@docsearch/css@3.8.3': {} - '@docsearch/react@3.6.0(@algolia/client-search@4.23.3)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0)': + '@docsearch/react@3.8.3(@algolia/client-search@5.20.0)(@types/react@19.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0) - '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) - '@docsearch/css': 3.6.0 - algoliasearch: 4.23.3 + '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.20.0)(algoliasearch@5.20.0) + '@docsearch/css': 3.8.3 + algoliasearch: 5.20.0 optionalDependencies: - '@types/react': 18.3.1 + '@types/react': 19.0.7 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - search-insights: 2.13.0 + search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/core@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': - dependencies: - '@babel/core': 7.24.5 - '@babel/generator': 7.24.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-transform-runtime': 7.24.3(@babel/core@7.24.5) - '@babel/preset-env': 7.24.5(@babel/core@7.24.5) - '@babel/preset-react': 7.24.1(@babel/core@7.24.5) - '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) - '@babel/runtime': 7.24.5 - '@babel/runtime-corejs3': 7.24.5 - '@babel/traverse': 7.24.5 - '@docusaurus/cssnano-preset': 3.3.2 - '@docusaurus/logger': 3.3.2 - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - autoprefixer: 10.4.19(postcss@8.4.38) - babel-loader: 9.1.3(@babel/core@7.24.5)(webpack@5.91.0) + '@docusaurus/babel@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/core': 7.26.0 + '@babel/generator': 7.26.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.26.0) + '@babel/preset-env': 7.26.0(@babel/core@7.26.0) + '@babel/preset-react': 7.26.3(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) + '@babel/runtime': 7.26.0 + '@babel/runtime-corejs3': 7.26.0 + '@babel/traverse': 7.26.5 + '@docusaurus/logger': 3.7.0 + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - acorn + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.7.0(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@babel/core': 7.26.0 + '@docusaurus/babel': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/cssnano-preset': 3.7.0 + '@docusaurus/logger': 3.7.0 + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + babel-loader: 9.2.1(@babel/core@7.26.0)(webpack@5.97.1) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.97.1) + css-loader: 6.11.0(webpack@5.97.1) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.97.1) + cssnano: 6.1.2(postcss@8.5.1) + file-loader: 6.2.0(webpack@5.97.1) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.9.2(webpack@5.97.1) + null-loader: 4.0.1(webpack@5.97.1) + postcss: 8.5.1 + postcss-loader: 7.3.4(postcss@8.5.1)(typescript@5.2.2)(webpack@5.97.1) + postcss-preset-env: 10.1.3(postcss@8.5.1) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.2.2)(webpack@5.97.1) + terser-webpack-plugin: 5.3.11(webpack@5.97.1) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.97.1))(webpack@5.97.1) + webpack: 5.97.1 + webpackbar: 6.0.1(webpack@5.97.1) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - acorn + - csso + - esbuild + - eslint + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - vue-template-compiler + - webpack-cli + + '@docusaurus/core@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@docusaurus/babel': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/bundler': 3.7.0(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.0(@types/react@19.0.7)(react@18.3.1) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 - clean-css: 5.3.3 - cli-table3: 0.6.4 + cli-table3: 0.6.5 combine-promises: 1.2.0 commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.91.0) - core-js: 3.37.0 - css-loader: 6.11.0(webpack@5.91.0) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.91.0) - cssnano: 6.1.2(postcss@8.4.38) + core-js: 3.40.0 del: 6.1.1 - detect-port: 1.5.1 + detect-port: 1.6.1 escape-html: 1.0.3 eta: 2.2.0 eval: 0.1.8 - file-loader: 6.2.0(webpack@5.91.0) - fs-extra: 11.2.0 - html-minifier-terser: 7.2.0 + fs-extra: 11.3.0 html-tags: 3.3.1 - html-webpack-plugin: 5.6.0(webpack@5.91.0) + html-webpack-plugin: 5.6.3(webpack@5.97.1) leven: 3.1.0 lodash: 4.17.21 - mini-css-extract-plugin: 2.9.0(webpack@5.91.0) p-map: 4.0.0 - postcss: 8.4.38 - postcss-loader: 7.3.4(postcss@8.4.38)(typescript@5.2.2)(webpack@5.91.0) prompts: 2.4.2 react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.0)(typescript@5.2.2)(webpack@5.91.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.2.2)(webpack@5.97.1) react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.91.0) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.97.1) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) - rtl-detect: 1.1.2 - semver: 7.6.0 - serve-handler: 6.1.5 + semver: 7.6.3 + serve-handler: 6.1.6 shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(webpack@5.91.0) - tslib: 2.6.2 + tslib: 2.8.1 update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.91.0))(webpack@5.91.0) - webpack: 5.91.0 + webpack: 5.97.1 webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.91.0) - webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.91.0) + webpack-dev-server: 4.15.2(webpack@5.97.1) + webpack-merge: 6.0.1 transitivePeerDependencies: - - '@docusaurus/types' + - '@docusaurus/faster' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8103,30 +9424,30 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/cssnano-preset@3.3.2': + '@docusaurus/cssnano-preset@3.7.0': dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.4.38) - postcss: 8.4.38 - postcss-sort-media-queries: 5.2.0(postcss@8.4.38) - tslib: 2.6.2 + cssnano-preset-advanced: 6.1.2(postcss@8.5.1) + postcss: 8.5.1 + postcss-sort-media-queries: 5.2.0(postcss@8.5.1) + tslib: 2.8.1 - '@docusaurus/logger@3.3.2': + '@docusaurus/logger@3.7.0': dependencies: chalk: 4.1.2 - tslib: 2.6.2 + tslib: 2.8.1 - '@docusaurus/mdx-loader@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/mdx-loader@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/logger': 3.3.2 - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@mdx-js/mdx': 3.0.1 + '@docusaurus/logger': 3.7.0 + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/mdx': 3.1.0(acorn@8.14.0) '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 - estree-util-value-to-estree: 3.1.1 - file-loader: 6.2.0(webpack@5.91.0) - fs-extra: 11.2.0 - image-size: 1.1.1 + estree-util-value-to-estree: 3.2.1 + file-loader: 6.2.0(webpack@5.97.1) + fs-extra: 11.3.0 + image-size: 1.2.0 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 react: 18.3.1 @@ -8137,65 +9458,70 @@ snapshots: remark-frontmatter: 5.0.0 remark-gfm: 4.0.0 stringify-object: 3.3.0 - tslib: 2.6.2 - unified: 11.0.4 + tslib: 2.8.1 + unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.91.0))(webpack@5.91.0) - vfile: 6.0.1 - webpack: 5.91.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.97.1))(webpack@5.97.1) + vfile: 6.0.3 + webpack: 5.97.1 transitivePeerDependencies: - - '@docusaurus/types' - '@swc/core' + - acorn - esbuild - supports-color - - typescript - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/module-type-aliases@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 2.0.5(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' transitivePeerDependencies: - '@swc/core' + - acorn - esbuild - supports-color - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': - dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/logger': 3.3.2 - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) + '@docusaurus/plugin-content-blog@3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/theme-common': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) cheerio: 1.0.0-rc.12 feed: 4.2.2 - fs-extra: 11.2.0 + fs-extra: 11.3.0 lodash: 4.17.21 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) reading-time: 1.5.0 srcset: 4.0.0 - tslib: 2.6.2 + tslib: 2.8.1 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.91.0 + webpack: 5.97.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8209,31 +9535,35 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': - dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/logger': 3.3.2 - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/module-type-aliases': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) + '@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 - fs-extra: 11.2.0 + fs-extra: 11.3.0 js-yaml: 4.1.0 lodash: 4.17.21 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.8.1 utility-types: 3.11.0 - webpack: 5.91.0 + webpack: 5.97.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8247,23 +9577,26 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-pages@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-content-pages@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - fs-extra: 11.2.0 + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 - webpack: 5.91.0 + tslib: 2.8.1 + webpack: 5.97.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8277,21 +9610,24 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-debug@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-debug@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - fs-extra: 11.2.0 + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-json-view-lite: 1.4.0(react@18.3.1) - tslib: 2.6.2 + react-json-view-lite: 1.5.0(react@18.3.1) + tslib: 2.8.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8305,19 +9641,22 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-analytics@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-google-analytics@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.8.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8331,20 +9670,52 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-gtag@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-google-gtag@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/gtag.js': 0.0.12 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - acorn + - bufferutil + - csso + - debug + - esbuild + - eslint + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - vue-template-compiler + - webpack-cli + + '@docusaurus/plugin-google-tag-manager@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8358,19 +9729,27 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-sitemap@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + sitemap: 7.1.2 + tslib: 2.8.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8384,24 +9763,26 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-sitemap@3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/plugin-svgr@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/logger': 3.3.2 - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - fs-extra: 11.2.0 + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@svgr/core': 8.1.0(typescript@5.2.2) + '@svgr/webpack': 8.1.0(typescript@5.2.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - sitemap: 7.1.1 - tslib: 2.6.2 + tslib: 2.8.1 + webpack: 5.97.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - acorn - bufferutil - csso - debug @@ -8415,30 +9796,34 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/preset-classic@3.3.2(@algolia/client-search@4.23.3)(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0)(typescript@5.2.2)': - dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-blog': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-docs': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-pages': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-debug': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-google-analytics': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-google-gtag': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-google-tag-manager': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-sitemap': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-classic': 3.3.2(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-search-algolia': 3.3.2(@algolia/client-search@4.23.3)(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0)(typescript@5.2.2) - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/preset-classic@3.7.0(@algolia/client-search@5.20.0)(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.2.2)': + dependencies: + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-content-blog': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-content-docs': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-content-pages': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-debug': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-google-analytics': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-google-gtag': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-google-tag-manager': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-sitemap': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-svgr': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/theme-classic': 3.7.0(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/theme-common': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.7.0(@algolia/client-search@5.20.0)(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.2.2) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' - '@types/react' + - acorn - bufferutil - csso - debug @@ -8455,44 +9840,47 @@ snapshots: '@docusaurus/react-loadable@6.0.0(react@18.3.1)': dependencies: - '@types/react': 18.3.1 + '@types/react': 19.0.7 react: 18.3.1 - '@docusaurus/theme-classic@3.3.2(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': - dependencies: - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/module-type-aliases': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-docs': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-pages': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-translations': 3.3.2 - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@mdx-js/react': 3.0.1(@types/react@18.3.1)(react@18.3.1) + '@docusaurus/theme-classic@3.7.0(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + dependencies: + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-content-docs': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/plugin-content-pages': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/theme-common': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.7.0 + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.0(@types/react@19.0.7)(react@18.3.1) clsx: 2.1.1 copy-text-to-clipboard: 3.2.0 - infima: 0.2.0-alpha.43 + infima: 0.2.0-alpha.45 lodash: 4.17.21 nprogress: 0.2.0 - postcss: 8.4.38 - prism-react-renderer: 2.3.1(react@18.3.1) + postcss: 8.5.1 + prism-react-renderer: 2.4.1(react@18.3.1) prismjs: 1.29.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) - rtlcss: 4.1.1 - tslib: 2.6.2 + rtlcss: 4.3.0 + tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: + - '@docusaurus/faster' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' - '@types/react' + - acorn - bufferutil - csso - debug @@ -8506,72 +9894,61 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-common@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2)': + '@docusaurus/theme-common@3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/mdx-loader': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/module-type-aliases': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-docs': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/plugin-content-pages': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/mdx-loader': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.3.1(react@18.3.1) + prism-react-renderer: 2.4.1(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - - '@docusaurus/types' - - '@parcel/css' - - '@rspack/core' - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug + - acorn - esbuild - - eslint - - lightningcss - supports-color - - typescript - uglify-js - - utf-8-validate - - vue-template-compiler - webpack-cli - '@docusaurus/theme-search-algolia@3.3.2(@algolia/client-search@4.23.3)(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.1)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0)(typescript@5.2.2)': - dependencies: - '@docsearch/react': 3.6.0(@algolia/client-search@4.23.3)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.13.0) - '@docusaurus/core': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/logger': 3.3.2 - '@docusaurus/plugin-content-docs': 3.3.2(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) - '@docusaurus/theme-translations': 3.3.2 - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-validation': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - algoliasearch: 4.23.3 - algoliasearch-helper: 3.19.0(algoliasearch@4.23.3) + '@docusaurus/theme-search-algolia@3.7.0(@algolia/client-search@5.20.0)(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(@types/react@19.0.7)(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.2.2)': + dependencies: + '@docsearch/react': 3.8.3(@algolia/client-search@5.20.0)(@types/react@19.0.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + '@docusaurus/core': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/plugin-content-docs': 3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2) + '@docusaurus/theme-common': 3.7.0(@docusaurus/plugin-content-docs@3.7.0(@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1))(acorn@8.14.0)(eslint@8.57.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.2.2))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.7.0 + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + algoliasearch: 5.20.0 + algoliasearch-helper: 3.23.1(algoliasearch@5.20.0) clsx: 2.1.1 eta: 2.2.0 - fs-extra: 11.2.0 + fs-extra: 11.3.0 lodash: 4.17.21 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - '@algolia/client-search' - - '@docusaurus/types' + - '@docusaurus/faster' + - '@mdx-js/react' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' - '@types/react' + - acorn - bufferutil - csso - debug @@ -8586,238 +9963,436 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-translations@3.3.2': + '@docusaurus/theme-translations@3.7.0': dependencies: - fs-extra: 11.2.0 - tslib: 2.6.2 + fs-extra: 11.3.0 + tslib: 2.8.1 - '@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@mdx-js/mdx': 3.0.1 + '@mdx-js/mdx': 3.1.0(acorn@8.14.0) '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 commander: 5.1.0 - joi: 17.13.1 + joi: 17.13.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' utility-types: 3.11.0 - webpack: 5.91.0 + webpack: 5.97.1 webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' + - acorn - esbuild - supports-color - uglify-js - webpack-cli - '@docusaurus/utils-common@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@docusaurus/utils-common@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - tslib: 2.6.2 - optionalDependencies: - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - acorn + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli - '@docusaurus/utils-validation@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2)': + '@docusaurus/utils-validation@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/logger': 3.3.2 - '@docusaurus/utils': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2) - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - joi: 17.13.1 + '@docusaurus/logger': 3.7.0 + '@docusaurus/utils': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fs-extra: 11.3.0 + joi: 17.13.3 js-yaml: 4.1.0 - tslib: 2.6.2 + lodash: 4.17.21 + tslib: 2.8.1 transitivePeerDependencies: - - '@docusaurus/types' - '@swc/core' + - acorn - esbuild + - react + - react-dom - supports-color - - typescript - uglify-js - webpack-cli - '@docusaurus/utils@3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.2.2)': + '@docusaurus/utils@3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/logger': 3.3.2 - '@docusaurus/utils-common': 3.3.2(@docusaurus/types@3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@svgr/webpack': 8.1.0(typescript@5.2.2) + '@docusaurus/logger': 3.7.0 + '@docusaurus/types': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.7.0(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.91.0) - fs-extra: 11.2.0 + file-loader: 6.2.0(webpack@5.97.1) + fs-extra: 11.3.0 github-slugger: 1.5.0 globby: 11.1.0 gray-matter: 4.0.3 - jiti: 1.21.0 + jiti: 1.21.7 js-yaml: 4.1.0 lodash: 4.17.21 - micromatch: 4.0.5 + micromatch: 4.0.8 prompts: 2.4.2 resolve-pathname: 3.0.0 shelljs: 0.8.5 - tslib: 2.6.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.91.0))(webpack@5.91.0) - webpack: 5.91.0 - optionalDependencies: - '@docusaurus/types': 3.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.97.1))(webpack@5.97.1) + utility-types: 3.11.0 + webpack: 5.97.1 transitivePeerDependencies: - '@swc/core' + - acorn - esbuild + - react + - react-dom - supports-color - - typescript - uglify-js - webpack-cli '@es-joy/jsdoccomment@0.41.0': dependencies: comment-parser: 1.4.1 - esquery: 1.5.0 + esquery: 1.6.0 jsdoc-type-pratt-parser: 4.0.0 + '@esbuild/aix-ppc64@0.24.2': + optional: true + '@esbuild/android-arm64@0.19.5': optional: true + '@esbuild/android-arm64@0.24.2': + optional: true + '@esbuild/android-arm@0.19.5': optional: true + '@esbuild/android-arm@0.24.2': + optional: true + '@esbuild/android-x64@0.19.5': optional: true + '@esbuild/android-x64@0.24.2': + optional: true + '@esbuild/darwin-arm64@0.19.5': optional: true + '@esbuild/darwin-arm64@0.24.2': + optional: true + '@esbuild/darwin-x64@0.19.5': optional: true + '@esbuild/darwin-x64@0.24.2': + optional: true + '@esbuild/freebsd-arm64@0.19.5': optional: true + '@esbuild/freebsd-arm64@0.24.2': + optional: true + '@esbuild/freebsd-x64@0.19.5': optional: true + '@esbuild/freebsd-x64@0.24.2': + optional: true + '@esbuild/linux-arm64@0.19.5': optional: true + '@esbuild/linux-arm64@0.24.2': + optional: true + '@esbuild/linux-arm@0.19.5': optional: true + '@esbuild/linux-arm@0.24.2': + optional: true + '@esbuild/linux-ia32@0.19.5': optional: true + '@esbuild/linux-ia32@0.24.2': + optional: true + '@esbuild/linux-loong64@0.19.5': optional: true + '@esbuild/linux-loong64@0.24.2': + optional: true + '@esbuild/linux-mips64el@0.19.5': optional: true + '@esbuild/linux-mips64el@0.24.2': + optional: true + '@esbuild/linux-ppc64@0.19.5': optional: true + '@esbuild/linux-ppc64@0.24.2': + optional: true + '@esbuild/linux-riscv64@0.19.5': optional: true + '@esbuild/linux-riscv64@0.24.2': + optional: true + '@esbuild/linux-s390x@0.19.5': optional: true + '@esbuild/linux-s390x@0.24.2': + optional: true + '@esbuild/linux-x64@0.19.5': optional: true + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + '@esbuild/netbsd-x64@0.19.5': optional: true + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.24.2': + optional: true + '@esbuild/openbsd-x64@0.19.5': optional: true + '@esbuild/openbsd-x64@0.24.2': + optional: true + '@esbuild/sunos-x64@0.19.5': optional: true + '@esbuild/sunos-x64@0.24.2': + optional: true + '@esbuild/win32-arm64@0.19.5': optional: true + '@esbuild/win32-arm64@0.24.2': + optional: true + '@esbuild/win32-ia32@0.19.5': optional: true + '@esbuild/win32-ia32@0.24.2': + optional: true + '@esbuild/win32-x64@0.19.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + '@esbuild/win32-x64@0.24.2': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.4.0(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.0(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@inquirer/checkbox@1.5.2': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + figures: 3.2.0 + + '@inquirer/confirm@2.0.17': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + chalk: 4.1.2 + + '@inquirer/core@5.1.2': + dependencies: + '@inquirer/type': 1.5.5 + '@types/mute-stream': 0.0.4 + '@types/node': 20.17.14 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + figures: 3.2.0 + mute-stream: 1.0.0 + run-async: 3.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + '@inquirer/core@6.0.0': dependencies: - eslint: 8.57.0 - eslint-visitor-keys: 3.4.3 + '@inquirer/type': 1.5.5 + '@types/mute-stream': 0.0.4 + '@types/node': 20.17.14 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + figures: 3.2.0 + mute-stream: 1.0.0 + run-async: 3.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 - '@eslint-community/regexpp@4.10.0': {} + '@inquirer/editor@1.2.15': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + chalk: 4.1.2 + external-editor: 3.1.0 - '@eslint/eslintrc@2.1.4': + '@inquirer/expand@1.1.16': dependencies: - ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + chalk: 4.1.2 + figures: 3.2.0 - '@eslint/js@8.57.0': {} + '@inquirer/input@1.2.16': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + chalk: 4.1.2 - '@hapi/hoek@9.3.0': {} + '@inquirer/password@1.1.16': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + chalk: 4.1.2 - '@hapi/topo@5.1.0': + '@inquirer/prompts@3.3.2': dependencies: - '@hapi/hoek': 9.3.0 + '@inquirer/checkbox': 1.5.2 + '@inquirer/confirm': 2.0.17 + '@inquirer/core': 6.0.0 + '@inquirer/editor': 1.2.15 + '@inquirer/expand': 1.1.16 + '@inquirer/input': 1.2.16 + '@inquirer/password': 1.1.16 + '@inquirer/rawlist': 1.2.16 + '@inquirer/select': 1.3.3 - '@humanwhocodes/config-array@0.11.14': + '@inquirer/rawlist@1.2.16': dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + chalk: 4.1.2 - '@humanwhocodes/module-importer@1.0.1': {} + '@inquirer/select@1.3.3': + dependencies: + '@inquirer/core': 6.0.0 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + figures: 3.2.0 - '@humanwhocodes/object-schema@2.0.3': {} + '@inquirer/type@1.5.5': + dependencies: + mute-stream: 1.0.0 - '@ipld/car@5.3.0': + '@ipld/car@5.4.0': dependencies: - '@ipld/dag-cbor': 9.2.0 - cborg: 4.2.0 - multiformats: 13.1.0 + '@ipld/dag-cbor': 9.2.2 + cborg: 4.2.7 + multiformats: 13.3.1 varint: 6.0.0 - '@ipld/dag-cbor@9.2.0': + '@ipld/dag-cbor@9.2.2': dependencies: - cborg: 4.2.0 - multiformats: 13.1.0 + cborg: 4.2.7 + multiformats: 13.3.1 - '@ipld/dag-cbor@9.2.1': + '@ipld/dag-json@10.2.3': dependencies: - cborg: 4.2.0 - multiformats: 13.3.0 + cborg: 4.2.7 + multiformats: 13.3.1 - '@ipld/dag-json@10.2.0': + '@ipld/dag-pb@4.1.3': dependencies: - cborg: 4.2.0 - multiformats: 13.1.0 + multiformats: 13.3.1 - '@ipld/dag-pb@4.1.0': + '@ipld/dag-ucan@3.4.5': dependencies: - multiformats: 13.1.0 + '@ipld/dag-cbor': 9.2.2 + '@ipld/dag-json': 10.2.3 + multiformats: 13.3.1 - '@ipld/dag-ucan@3.4.0': + '@ipld/unixfs@2.2.0': dependencies: - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-json': 10.2.0 + '@ipld/dag-pb': 4.1.3 + '@multiformats/murmur3': 2.1.8 + '@perma/map': 1.0.3 + actor: 2.3.1 multiformats: 11.0.2 + protobufjs: 7.4.0 + rabin-rs: 2.1.0 - '@ipld/unixfs@2.2.0': + '@ipld/unixfs@3.0.0': dependencies: - '@ipld/dag-pb': 4.1.0 + '@ipld/dag-pb': 4.1.3 '@multiformats/murmur3': 2.1.8 '@perma/map': 1.0.3 actor: 2.3.1 - multiformats: 11.0.2 - protobufjs: 7.2.6 + multiformats: 13.3.1 + protobufjs: 7.4.0 rabin-rs: 2.1.0 '@isaacs/cliui@8.0.2': @@ -8840,14 +10415,14 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.12.10 - '@types/yargs': 17.0.32 + '@types/node': 20.17.14 + '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.5': + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} @@ -8856,64 +10431,66 @@ snapshots: '@jridgewell/source-map@0.3.6': dependencies: - '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@leichtgewicht/ip-codec@2.0.5': {} - '@mdx-js/mdx@3.0.1': + '@mdx-js/mdx@3.1.0(acorn@8.14.0)': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 collapse-white-space: 2.1.0 devlop: 1.1.0 - estree-util-build-jsx: 3.0.1 estree-util-is-identifier-name: 3.0.0 - estree-util-to-js: 2.0.0 + estree-util-scope: 1.0.0 estree-walker: 3.0.3 - hast-util-to-estree: 3.1.0 - hast-util-to-jsx-runtime: 2.3.0 + hast-util-to-jsx-runtime: 2.3.2 markdown-extensions: 2.0.0 - periscopic: 3.1.0 - remark-mdx: 3.0.1 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.0(acorn@8.14.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.0 remark-parse: 11.0.0 - remark-rehype: 11.1.0 + remark-rehype: 11.1.1 source-map: 0.7.4 - unified: 11.0.4 + unified: 11.0.5 unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 transitivePeerDependencies: + - acorn - supports-color - '@mdx-js/react@3.0.1(@types/react@18.3.1)(react@18.3.1)': + '@mdx-js/react@3.1.0(@types/react@19.0.7)(react@18.3.1)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 18.3.1 + '@types/react': 19.0.7 react: 18.3.1 '@multiformats/murmur3@2.1.8': dependencies: - multiformats: 13.1.0 + multiformats: 13.3.1 murmurhash3js-revisited: 3.0.0 - '@noble/curves@1.4.0': + '@noble/curves@1.8.1': dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.7.1 '@noble/ed25519@1.7.3': {} - '@noble/hashes@1.4.0': {} + '@noble/hashes@1.7.1': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -8925,7 +10502,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 + fastq: 1.18.0 '@perma/map@1.0.3': dependencies: @@ -8941,7 +10518,7 @@ snapshots: dependencies: graceful-fs: 4.2.10 - '@pnpm/npm-conf@2.2.2': + '@pnpm/npm-conf@2.3.1': dependencies: '@pnpm/config.env-replace': 1.1.0 '@pnpm/network.ca-file': 1.0.2 @@ -8949,7 +10526,7 @@ snapshots: '@polka/url@0.5.0': {} - '@polka/url@1.0.0-next.25': {} + '@polka/url@1.0.0-next.28': {} '@protobufjs/aspromise@1.1.2': {} @@ -8974,12 +10551,12 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@scure/base@1.1.6': {} + '@scure/base@1.2.4': {} - '@scure/bip39@1.3.0': + '@scure/bip39@1.5.4': dependencies: - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.6 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.4 '@sideway/address@4.1.5': dependencies: @@ -8997,10 +10574,6 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@sinonjs/commons@2.0.0': - dependencies: - type-detect: 4.0.8 - '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -9009,17 +10582,27 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers@11.2.2': + '@sinonjs/fake-timers@11.3.1': dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/samsam@8.0.0': + '@sinonjs/samsam@8.0.2': dependencies: - '@sinonjs/commons': 2.0.0 + '@sinonjs/commons': 3.0.1 lodash.get: 4.4.2 - type-detect: 4.0.8 + type-detect: 4.1.0 + + '@sinonjs/text-encoding@0.7.3': {} - '@sinonjs/text-encoding@0.7.2': {} + '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + invariant: 2.2.4 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 '@slorber/remark-comment@1.0.0': dependencies: @@ -9029,54 +10612,54 @@ snapshots: '@storacha/one-webcrypto@1.0.1': {} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.24.5)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 - '@svgr/babel-preset@8.1.0(@babel/core@7.24.5)': + '@svgr/babel-preset@8.1.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.24.5) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.24.5) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.26.0) '@svgr/core@8.1.0(typescript@5.2.2)': dependencies: - '@babel/core': 7.24.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@5.2.2) snake-case: 3.0.4 @@ -9086,13 +10669,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.26.5 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.2.2))': dependencies: - '@babel/core': 7.24.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) '@svgr/core': 8.1.0(typescript@5.2.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -9104,17 +10687,17 @@ snapshots: '@svgr/core': 8.1.0(typescript@5.2.2) cosmiconfig: 8.3.6(typescript@5.2.2) deepmerge: 4.3.1 - svgo: 3.2.0 + svgo: 3.3.2 transitivePeerDependencies: - typescript '@svgr/webpack@8.1.0(typescript@5.2.2)': dependencies: - '@babel/core': 7.24.5 - '@babel/plugin-transform-react-constant-elements': 7.24.1(@babel/core@7.24.5) - '@babel/preset-env': 7.24.5(@babel/core@7.24.5) - '@babel/preset-react': 7.24.1(@babel/core@7.24.5) - '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.26.0) + '@babel/preset-env': 7.26.0(@babel/core@7.26.0) + '@babel/preset-react': 7.26.3(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) '@svgr/core': 8.1.0(typescript@5.2.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.2.2)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.2.2))(typescript@5.2.2) @@ -9130,67 +10713,76 @@ snapshots: '@types/acorn@4.0.6': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 - '@types/assert@1.5.10': {} + '@types/assert@1.5.11': {} '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/bonjour@3.5.13': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 + + '@types/configstore@6.0.2': {} '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 4.19.0 - '@types/node': 20.12.10 + '@types/express-serve-static-core': 5.0.5 + '@types/node': 20.17.14 '@types/connect@3.4.38': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/debug@4.1.12': dependencies: - '@types/ms': 0.7.34 + '@types/ms': 2.1.0 '@types/eslint-scope@3.7.7': dependencies: - '@types/eslint': 8.56.10 - '@types/estree': 1.0.5 + '@types/eslint': 9.6.1 + '@types/estree': 1.0.6 - '@types/eslint@8.56.10': + '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 - '@types/estree@1.0.5': {} + '@types/estree@1.0.6': {} + + '@types/express-serve-static-core@4.19.6': + dependencies: + '@types/node': 20.17.14 + '@types/qs': 6.9.18 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 - '@types/express-serve-static-core@4.19.0': + '@types/express-serve-static-core@5.0.5': dependencies: - '@types/node': 20.12.10 - '@types/qs': 6.9.15 + '@types/node': 20.17.14 + '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express@4.17.21': dependencies: '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.0 - '@types/qs': 6.9.15 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.9.18 '@types/serve-static': 1.15.7 '@types/gtag.js@0.0.12': {} '@types/hast@3.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 '@types/history@4.7.11': {} @@ -9200,9 +10792,9 @@ snapshots: '@types/http-errors@2.0.4': {} - '@types/http-proxy@1.17.14': + '@types/http-proxy@1.17.15': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/inquirer@9.0.7': dependencies: @@ -9221,9 +10813,9 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/mdast@4.0.3': + '@types/mdast@4.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 '@types/mdx@2.0.13': {} @@ -9231,50 +10823,51 @@ snapshots: '@types/minimatch@3.0.5': {} - '@types/mocha@10.0.6': {} + '@types/mocha@10.0.10': {} - '@types/ms@0.7.34': {} + '@types/ms@2.1.0': {} + + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 20.17.14 '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/node@17.0.45': {} - '@types/node@20.12.10': + '@types/node@20.17.14': dependencies: - undici-types: 5.26.5 + undici-types: 6.19.8 '@types/parse-json@4.0.2': {} - '@types/prismjs@1.26.4': {} + '@types/prismjs@1.26.5': {} - '@types/prop-types@15.7.12': {} - - '@types/qs@6.9.15': {} + '@types/qs@6.9.18': {} '@types/range-parser@1.2.7': {} '@types/react-router-config@5.0.11': dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 '@types/react-router': 5.1.20 '@types/react-router-dom@5.3.3': dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 '@types/react-router': 5.1.20 '@types/react-router@5.1.20': dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.1 + '@types/react': 19.0.7 - '@types/react@18.3.1': + '@types/react@19.0.7': dependencies: - '@types/prop-types': 15.7.12 csstype: 3.1.3 '@types/retry@0.12.0': {} @@ -9283,14 +10876,14 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/semver@7.5.8': {} '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/serve-index@1.9.4': dependencies: @@ -9299,7 +10892,7 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/send': 0.17.4 '@types/sinon@10.0.20': @@ -9310,58 +10903,65 @@ snapshots: '@types/sockjs@0.3.36': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/through@0.0.33': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 + + '@types/unist@2.0.11': {} - '@types/unist@2.0.10': {} + '@types/unist@3.0.3': {} - '@types/unist@3.0.2': {} + '@types/update-notifier@6.0.8': + dependencies: + '@types/configstore': 6.0.2 + boxen: 7.1.1 '@types/varint@6.0.3': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 - '@types/ws@8.5.10': + '@types/wrap-ansi@3.0.0': {} + + '@types/ws@8.5.13': dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.32': + '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + debug: 4.4.0(supports-color@8.1.1) + eslint: 8.57.1 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.3.3) + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 + debug: 4.4.0(supports-color@8.1.1) + eslint: 8.57.1 optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: @@ -9372,13 +10972,13 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.3.3) + debug: 4.4.0(supports-color@8.1.1) + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: @@ -9390,27 +10990,27 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.3.3) + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.3.3) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.3.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) - eslint: 8.57.0 - semver: 7.6.0 + eslint: 8.57.1 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript @@ -9422,85 +11022,85 @@ snapshots: '@ucanto/client@9.0.1': dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 - '@ucanto/core@10.0.1': + '@ucanto/core@10.2.1': dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-ucan': 3.4.0 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 + '@ipld/car': 5.4.0 + '@ipld/dag-cbor': 9.2.2 + '@ipld/dag-ucan': 3.4.5 + '@ucanto/interface': 10.1.1 + multiformats: 13.3.1 - '@ucanto/interface@10.0.1': + '@ucanto/interface@10.1.1': dependencies: - '@ipld/dag-ucan': 3.4.0 - multiformats: 11.0.2 + '@ipld/dag-ucan': 3.4.5 + multiformats: 13.3.1 - '@ucanto/principal@9.0.1': + '@ucanto/principal@9.0.2': dependencies: - '@ipld/dag-ucan': 3.4.0 - '@noble/curves': 1.4.0 + '@ipld/dag-ucan': 3.4.5 + '@noble/curves': 1.8.1 '@noble/ed25519': 1.7.3 - '@noble/hashes': 1.4.0 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 + '@noble/hashes': 1.7.1 + '@ucanto/interface': 10.1.1 + multiformats: 13.3.1 one-webcrypto: 1.0.3 - '@ucanto/server@10.0.0': + '@ucanto/server@10.1.0': dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/principal': 9.0.1 - '@ucanto/validator': 9.0.2 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 + '@ucanto/validator': 9.0.3 '@ucanto/transport@9.1.1': dependencies: - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 - '@ucanto/validator@9.0.2': + '@ucanto/validator@9.0.3': dependencies: - '@ipld/car': 5.3.0 - '@ipld/dag-cbor': 9.2.0 - '@ucanto/core': 10.0.1 - '@ucanto/interface': 10.0.1 - multiformats: 11.0.2 + '@ipld/car': 5.4.0 + '@ipld/dag-cbor': 9.2.2 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + multiformats: 13.3.1 - '@ungap/structured-clone@1.2.0': {} + '@ungap/structured-clone@1.2.1': {} - '@vue/compiler-core@3.4.27': + '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.24.5 - '@vue/shared': 3.4.27 + '@babel/parser': 7.26.5 + '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 - source-map-js: 1.2.0 + source-map-js: 1.2.1 - '@vue/compiler-dom@3.4.27': + '@vue/compiler-dom@3.5.13': dependencies: - '@vue/compiler-core': 3.4.27 - '@vue/shared': 3.4.27 + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/compiler-sfc@3.4.27': + '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.24.5 - '@vue/compiler-core': 3.4.27 - '@vue/compiler-dom': 3.4.27 - '@vue/compiler-ssr': 3.4.27 - '@vue/shared': 3.4.27 + '@babel/parser': 7.26.5 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 estree-walker: 2.0.2 - magic-string: 0.30.10 - postcss: 8.4.38 - source-map-js: 1.2.0 + magic-string: 0.30.17 + postcss: 8.5.1 + source-map-js: 1.2.1 - '@vue/compiler-ssr@3.4.27': + '@vue/compiler-ssr@3.5.13': dependencies: - '@vue/compiler-dom': 3.4.27 - '@vue/shared': 3.4.27 + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 - '@vue/shared@3.4.27': {} + '@vue/shared@3.5.13': {} '@web-std/blob@3.0.5': dependencies: @@ -9511,129 +11111,240 @@ snapshots: dependencies: web-streams-polyfill: 3.3.3 - '@web3-storage/content-claims@4.0.5': + '@web3-storage/access@20.1.1': dependencies: + '@ipld/car': 5.4.0 + '@ipld/dag-ucan': 3.4.5 + '@scure/bip39': 1.5.4 + '@storacha/one-webcrypto': 1.0.1 '@ucanto/client': 9.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/server': 10.0.0 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 '@ucanto/transport': 9.1.1 - carstream: 1.1.1 + '@ucanto/validator': 9.0.3 + '@web3-storage/capabilities': 18.0.1 + '@web3-storage/did-mailto': 2.1.0 + bigint-mod-arith: 3.3.1 + conf: 11.0.2 multiformats: 12.1.3 + p-defer: 4.0.1 + type-fest: 4.33.0 + uint8arrays: 4.0.10 + + '@web3-storage/blob-index@1.0.5': + dependencies: + '@ipld/dag-cbor': 9.2.2 + '@storacha/one-webcrypto': 1.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@web3-storage/capabilities': 18.0.1 + carstream: 2.3.0 + multiformats: 13.3.1 + uint8arrays: 5.1.0 + + '@web3-storage/capabilities@17.4.1': + dependencies: + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 + '@ucanto/transport': 9.1.1 + '@ucanto/validator': 9.0.3 + '@web3-storage/data-segment': 5.3.0 + uint8arrays: 5.1.0 + + '@web3-storage/capabilities@18.0.1': + dependencies: + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 + '@ucanto/transport': 9.1.1 + '@ucanto/validator': 9.0.3 + '@web3-storage/data-segment': 5.3.0 + uint8arrays: 5.1.0 - '@web3-storage/content-claims@5.0.0': + '@web3-storage/content-claims@4.0.5': dependencies: '@ucanto/client': 9.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/server': 10.0.0 + '@ucanto/interface': 10.1.1 + '@ucanto/server': 10.1.0 '@ucanto/transport': 9.1.1 - carstream: 2.1.0 - multiformats: 13.1.0 + carstream: 1.1.1 + multiformats: 12.1.3 - '@web3-storage/content-claims@5.1.0': + '@web3-storage/content-claims@5.1.3': dependencies: '@ucanto/client': 9.0.1 - '@ucanto/interface': 10.0.1 - '@ucanto/server': 10.0.0 + '@ucanto/interface': 10.1.1 + '@ucanto/server': 10.1.0 '@ucanto/transport': 9.1.1 - carstream: 2.1.0 - multiformats: 13.1.0 + carstream: 2.3.0 + multiformats: 13.3.1 - '@web3-storage/data-segment@4.0.0': + '@web3-storage/data-segment@5.3.0': dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 11.0.2 + '@ipld/dag-cbor': 9.2.2 + multiformats: 13.3.1 sync-multihash-sha2: 1.0.0 - '@web3-storage/data-segment@5.1.0': + '@web3-storage/did-mailto@2.1.0': {} + + '@web3-storage/filecoin-api@8.0.0': dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 11.0.2 - sync-multihash-sha2: 1.0.0 + '@ipld/dag-ucan': 3.4.5 + '@ucanto/client': 9.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/server': 10.1.0 + '@ucanto/transport': 9.1.1 + '@web3-storage/capabilities': 18.0.1 + '@web3-storage/content-claims': 5.1.3 + '@web3-storage/data-segment': 5.3.0 + fr32-sha2-256-trunc254-padded-binary-tree-multihash: 3.3.0 + p-map: 6.0.0 - '@web3-storage/data-segment@5.2.0': + '@web3-storage/filecoin-client@3.3.5': dependencies: - '@ipld/dag-cbor': 9.2.1 - multiformats: 13.3.0 - sync-multihash-sha2: 1.0.0 + '@ipld/dag-ucan': 3.4.5 + '@ucanto/client': 9.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/transport': 9.1.1 + '@web3-storage/capabilities': 18.0.1 '@web3-storage/sigv4@1.0.2': dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.7.1 + + '@web3-storage/upload-api@19.0.0': + dependencies: + '@ucanto/client': 9.0.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 + '@ucanto/server': 10.1.0 + '@ucanto/transport': 9.1.1 + '@ucanto/validator': 9.0.3 + '@web3-storage/access': 20.1.1 + '@web3-storage/blob-index': 1.0.5 + '@web3-storage/capabilities': 18.0.1 + '@web3-storage/content-claims': 5.1.3 + '@web3-storage/did-mailto': 2.1.0 + '@web3-storage/filecoin-api': 8.0.0 + multiformats: 12.1.3 + uint8arrays: 5.1.0 + + '@web3-storage/upload-client@17.1.3': + dependencies: + '@ipld/car': 5.4.0 + '@ipld/dag-cbor': 9.2.2 + '@ipld/dag-ucan': 3.4.5 + '@ipld/unixfs': 2.2.0 + '@ucanto/client': 9.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/transport': 9.1.1 + '@web3-storage/blob-index': 1.0.5 + '@web3-storage/capabilities': 18.0.1 + '@web3-storage/data-segment': 5.3.0 + '@web3-storage/filecoin-client': 3.3.5 + ipfs-utils: 9.0.14(encoding@0.1.13) + multiformats: 12.1.3 + p-retry: 5.1.2 + varint: 6.0.0 + transitivePeerDependencies: + - encoding + + '@web3-storage/w3up-client@16.5.2': + dependencies: + '@ipld/dag-ucan': 3.4.5 + '@ucanto/client': 9.0.1 + '@ucanto/core': 10.2.1 + '@ucanto/interface': 10.1.1 + '@ucanto/principal': 9.0.2 + '@ucanto/transport': 9.1.1 + '@web3-storage/access': 20.1.1 + '@web3-storage/blob-index': 1.0.5 + '@web3-storage/capabilities': 17.4.1 + '@web3-storage/did-mailto': 2.1.0 + '@web3-storage/filecoin-client': 3.3.5 + '@web3-storage/upload-client': 17.1.3 + transitivePeerDependencies: + - encoding - '@webassemblyjs/ast@1.12.1': + '@webassemblyjs/ast@1.14.1': dependencies: - '@webassemblyjs/helper-numbers': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - '@webassemblyjs/helper-api-error@1.11.6': {} + '@webassemblyjs/helper-api-error@1.13.2': {} - '@webassemblyjs/helper-buffer@1.12.1': {} + '@webassemblyjs/helper-buffer@1.14.1': {} - '@webassemblyjs/helper-numbers@1.11.6': + '@webassemblyjs/helper-numbers@1.13.2': dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.11.6 - '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 '@xtuc/long': 4.2.2 - '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - '@webassemblyjs/helper-wasm-section@1.12.1': + '@webassemblyjs/helper-wasm-section@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/ieee754@1.11.6': + '@webassemblyjs/ieee754@1.13.2': dependencies: '@xtuc/ieee754': 1.2.0 - '@webassemblyjs/leb128@1.11.6': + '@webassemblyjs/leb128@1.13.2': dependencies: '@xtuc/long': 4.2.2 - '@webassemblyjs/utf8@1.11.6': {} + '@webassemblyjs/utf8@1.13.2': {} - '@webassemblyjs/wasm-edit@1.12.1': + '@webassemblyjs/wasm-edit@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/helper-wasm-section': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-opt': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - '@webassemblyjs/wast-printer': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 - '@webassemblyjs/wasm-gen@1.12.1': + '@webassemblyjs/wasm-gen@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wasm-opt@1.12.1': + '@webassemblyjs/wasm-opt@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wasm-parser@1.12.1': + '@webassemblyjs/wasm-parser@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-api-error': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wast-printer@1.12.1': + '@webassemblyjs/wast-printer@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 '@xtuc/ieee754@1.2.0': {} @@ -9648,21 +11359,19 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-assertions@1.9.0(acorn@8.11.3): - dependencies: - acorn: 8.11.3 - - acorn-jsx@5.3.2(acorn@8.11.3): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.11.3 + acorn: 8.14.0 acorn-loose@8.4.0: dependencies: - acorn: 8.11.3 + acorn: 8.14.0 - acorn-walk@8.3.2: {} + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.0 - acorn@8.11.3: {} + acorn@8.14.0: {} actor@2.3.1: {} @@ -9673,22 +11382,17 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - aggregate-error@4.0.1: - dependencies: - clean-stack: 4.2.0 - indent-string: 5.0.0 - - ajv-formats@2.1.1(ajv@8.13.0): + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: - ajv: 8.13.0 + ajv: 8.17.1 ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 - ajv-keywords@5.1.0(ajv@8.13.0): + ajv-keywords@5.1.0(ajv@8.17.1): dependencies: - ajv: 8.13.0 + ajv: 8.17.1 fast-deep-equal: 3.1.3 ajv@6.12.6: @@ -9698,41 +11402,43 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.13.0: + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.4.1 - algoliasearch-helper@3.19.0(algoliasearch@4.23.3): + algoliasearch-helper@3.23.1(algoliasearch@5.20.0): dependencies: '@algolia/events': 4.0.1 - algoliasearch: 4.23.3 - - algoliasearch@4.23.3: - dependencies: - '@algolia/cache-browser-local-storage': 4.23.3 - '@algolia/cache-common': 4.23.3 - '@algolia/cache-in-memory': 4.23.3 - '@algolia/client-account': 4.23.3 - '@algolia/client-analytics': 4.23.3 - '@algolia/client-common': 4.23.3 - '@algolia/client-personalization': 4.23.3 - '@algolia/client-search': 4.23.3 - '@algolia/logger-common': 4.23.3 - '@algolia/logger-console': 4.23.3 - '@algolia/recommend': 4.23.3 - '@algolia/requester-browser-xhr': 4.23.3 - '@algolia/requester-common': 4.23.3 - '@algolia/requester-node-http': 4.23.3 - '@algolia/transporter': 4.23.3 + algoliasearch: 5.20.0 + + algoliasearch@5.20.0: + dependencies: + '@algolia/client-abtesting': 5.20.0 + '@algolia/client-analytics': 5.20.0 + '@algolia/client-common': 5.20.0 + '@algolia/client-insights': 5.20.0 + '@algolia/client-personalization': 5.20.0 + '@algolia/client-query-suggestions': 5.20.0 + '@algolia/client-search': 5.20.0 + '@algolia/ingestion': 1.20.0 + '@algolia/monitoring': 1.20.0 + '@algolia/recommend': 5.20.0 + '@algolia/requester-browser-xhr': 5.20.0 + '@algolia/requester-fetch': 5.20.0 + '@algolia/requester-node-http': 5.20.0 ansi-align@3.0.1: dependencies: string-width: 4.2.3 - ansi-colors@4.1.1: {} + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 ansi-escapes@5.0.0: dependencies: @@ -9740,14 +11446,22 @@ snapshots: ansi-escapes@6.2.1: {} + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-html-community@0.0.8: {} + ansi-regex@1.1.1: {} + ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-sequence-parser@1.1.1: {} + ansi-styles@2.2.1: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -9758,7 +11472,7 @@ snapshots: ansi-styles@6.2.1: {} - ansicolors@0.3.2: {} + any-promise@1.3.0: {} any-signal@3.0.1: {} @@ -9767,6 +11481,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + archy@0.0.2: {} + are-docs-informative@0.0.2: {} arg@5.0.2: {} @@ -9777,10 +11493,10 @@ snapshots: argparse@2.0.1: {} - array-buffer-byte-length@1.0.1: + array-buffer-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 + call-bound: 1.0.3 + is-array-buffer: 3.0.5 array-differ@3.0.0: {} @@ -9788,82 +11504,81 @@ snapshots: array-union@2.1.0: {} - arraybuffer.prototype.slice@1.0.3: + arraybuffer.prototype.slice@1.0.4: dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.23.9 es-errors: 1.3.0 - get-intrinsic: 1.2.4 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 + get-intrinsic: 1.2.7 + is-array-buffer: 3.0.5 arrify@2.0.1: {} assert@2.1.0: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 is-nan: 1.3.2 object-is: 1.1.6 - object.assign: 4.1.5 + object.assign: 4.1.7 util: 0.12.5 - astring@1.8.6: {} + astring@1.9.0: {} at-least-node@1.0.0: {} atomically@2.0.3: dependencies: stubborn-fs: 1.2.5 - when-exit: 2.1.2 + when-exit: 2.1.4 - autoprefixer@10.4.19(postcss@8.4.38): + autoprefixer@10.4.20(postcss@8.5.1): dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001616 + browserslist: 4.24.4 + caniuse-lite: 1.0.30001695 fraction.js: 4.3.7 normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.38 + picocolors: 1.1.1 + postcss: 8.5.1 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - babel-loader@9.1.3(@babel/core@7.24.5)(webpack@5.91.0): + babel-loader@9.2.1(@babel/core@7.26.0)(webpack@5.97.1): dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 find-cache-dir: 4.0.0 - schema-utils: 4.2.0 - webpack: 5.91.0 + schema-utils: 4.3.0 + webpack: 5.97.1 babel-plugin-dynamic-import-node@2.3.3: dependencies: - object.assign: 4.1.5 + object.assign: 4.1.7 - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.5): + babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.0): dependencies: - '@babel/compat-data': 7.24.4 - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) + '@babel/compat-data': 7.26.5 + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.5): + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.26.0): dependencies: - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) + core-js-compat: 3.40.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.5): + babel-plugin-polyfill-regenerator@0.6.3(@babel/core@7.26.0): dependencies: - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -9875,6 +11590,8 @@ snapshots: batch@0.6.1: {} + big-integer@1.6.52: {} + big.js@5.2.2: {} bigint-mod-arith@3.3.1: {} @@ -9898,7 +11615,7 @@ snapshots: it-take: 2.0.1 multiformats: 11.0.2 - body-parser@1.20.2: + body-parser@1.20.3: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -9908,14 +11625,14 @@ snapshots: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: - supports-color - bonjour-service@1.2.1: + bonjour-service@1.3.0: dependencies: fast-deep-equal: 3.1.3 multicast-dns: 7.2.5 @@ -9937,13 +11654,28 @@ snapshots: dependencies: ansi-align: 3.0.1 camelcase: 7.0.1 - chalk: 5.3.0 + chalk: 5.4.1 cli-boxes: 3.0.0 string-width: 5.1.2 type-fest: 2.19.0 widest-line: 4.0.1 wrap-ansi: 8.1.0 + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.4.1 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.33.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + + bplist-parser@0.2.0: + dependencies: + big-integer: 1.6.52 + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -9953,20 +11685,20 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 browser-readablestream-to-it@1.0.3: {} browser-stdout@1.3.1: {} - browserslist@4.23.0: + browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001616 - electron-to-chromium: 1.4.757 - node-releases: 2.0.14 - update-browserslist-db: 1.0.15(browserslist@4.23.0) + caniuse-lite: 1.0.30001695 + electron-to-chromium: 1.5.84 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) buffer-from@1.1.2: {} @@ -9977,21 +11709,25 @@ snapshots: builtin-modules@3.3.0: {} + bundle-name@3.0.0: + dependencies: + run-applescript: 5.0.0 + bytes@3.0.0: {} bytes@3.1.2: {} - c8@10.1.2: + c8@10.1.3: dependencies: - '@bcoe/v8-coverage': 0.2.3 + '@bcoe/v8-coverage': 1.0.2 '@istanbuljs/schema': 0.1.3 find-up: 5.0.0 - foreground-child: 3.2.1 + foreground-child: 3.3.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.1.7 test-exclude: 7.0.1 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 yargs: 17.7.2 yargs-parser: 21.1.1 @@ -10006,7 +11742,7 @@ snapshots: istanbul-reports: 3.1.7 rimraf: 3.0.2 test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 yargs: 16.2.0 yargs-parser: 20.2.9 @@ -10021,7 +11757,7 @@ snapshots: istanbul-reports: 3.1.7 rimraf: 3.0.2 test-exclude: 6.0.0 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 yargs: 17.7.2 yargs-parser: 21.1.1 @@ -10037,14 +11773,23 @@ snapshots: normalize-url: 8.0.1 responselike: 3.0.0 - call-bind@1.0.7: + call-bind-apply-helpers@1.0.1: dependencies: - es-define-property: 1.0.0 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + get-intrinsic: 1.2.7 set-function-length: 1.2.2 + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.7 + callsite@1.0.0: {} callsites@3.1.0: {} @@ -10052,7 +11797,7 @@ snapshots: camel-case@4.1.2: dependencies: pascal-case: 3.1.2 - tslib: 2.6.2 + tslib: 2.8.1 camelcase@6.3.0: {} @@ -10062,34 +11807,37 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001616 + browserslist: 4.24.4 + caniuse-lite: 1.0.30001695 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001616: {} - - cardinal@2.1.1: - dependencies: - ansicolors: 0.3.2 - redeyed: 2.1.1 + caniuse-lite@1.0.30001695: {} carstream@1.1.1: dependencies: - '@ipld/dag-cbor': 9.2.0 + '@ipld/dag-cbor': 9.2.2 multiformats: 12.1.3 uint8arraylist: 2.4.8 - carstream@2.1.0: + carstream@2.3.0: dependencies: - '@ipld/dag-cbor': 9.2.0 - multiformats: 13.1.0 + '@ipld/dag-cbor': 9.2.2 + multiformats: 13.3.1 uint8arraylist: 2.4.8 - cborg@4.2.0: {} + cborg@4.2.7: {} ccount@2.0.1: {} + chalk@1.0.0: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 1.0.3 + strip-ansi: 2.0.1 + supports-color: 1.3.1 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -10103,6 +11851,8 @@ snapshots: chalk@5.3.0: {} + chalk@5.4.1: {} + char-regex@1.0.2: {} character-entities-html4@2.1.0: {} @@ -10113,6 +11863,8 @@ snapshots: character-reference-invalid@2.0.1: {} + chardet@0.7.0: {} + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -10120,34 +11872,22 @@ snapshots: css-what: 6.1.0 domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 cheerio@1.0.0-rc.12: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - - chokidar@3.5.3: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + parse5: 7.2.1 + parse5-htmlparser2-tree-adapter: 7.1.0 chokidar@3.6.0: dependencies: anymatch: 3.1.3 - braces: 3.0.2 + braces: 3.0.3 glob-parent: 5.1.2 is-binary-path: 2.1.0 is-glob: 4.0.3 @@ -10156,7 +11896,7 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - chrome-trace-event@1.0.3: {} + chrome-trace-event@1.0.4: {} ci-info@3.9.0: {} @@ -10166,19 +11906,24 @@ snapshots: clean-stack@2.2.0: {} - clean-stack@4.2.0: - dependencies: - escape-string-regexp: 5.0.0 - cli-boxes@3.0.0: {} cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + cli-spinners@2.9.2: {} - cli-table3@0.6.4: + cli-table3@0.6.5: dependencies: string-width: 4.2.3 optionalDependencies: @@ -10189,6 +11934,8 @@ snapshots: slice-ansi: 5.0.0 string-width: 5.1.2 + cli-width@4.1.0: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -10249,16 +11996,16 @@ snapshots: compressible@2.0.18: dependencies: - mime-db: 1.52.0 + mime-db: 1.53.0 - compression@1.7.4: + compression@1.7.5: dependencies: - accepts: 1.3.8 - bytes: 3.0.0 + bytes: 3.1.2 compressible: 2.0.18 debug: 2.6.9 + negotiator: 0.6.4 on-headers: 1.0.2 - safe-buffer: 5.1.2 + safe-buffer: 5.2.1 vary: 1.1.2 transitivePeerDependencies: - supports-color @@ -10267,14 +12014,14 @@ snapshots: conf@11.0.2: dependencies: - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) atomically: 2.0.3 debounce-fn: 5.1.2 dot-prop: 7.2.0 env-paths: 3.0.0 json-schema-typed: 8.0.1 - semver: 7.6.0 + semver: 7.6.3 config-chain@1.1.13: dependencies: @@ -10289,9 +12036,16 @@ snapshots: write-file-atomic: 3.0.3 xdg-basedir: 5.1.0 + configstore@7.0.0: + dependencies: + atomically: 2.0.3 + dot-prop: 9.0.0 + graceful-fs: 4.2.11 + xdg-basedir: 5.1.0 + connect-history-api-fallback@2.0.0: {} - consola@2.15.3: {} + consola@3.4.0: {} content-disposition@0.5.2: {} @@ -10305,7 +12059,7 @@ snapshots: cookie-signature@1.0.6: {} - cookie@0.6.0: {} + cookie@0.7.1: {} copy-file@11.0.0: dependencies: @@ -10314,23 +12068,23 @@ snapshots: copy-text-to-clipboard@3.2.0: {} - copy-webpack-plugin@11.0.0(webpack@5.91.0): + copy-webpack-plugin@11.0.0(webpack@5.97.1): dependencies: - fast-glob: 3.3.2 + fast-glob: 3.3.3 glob-parent: 6.0.2 globby: 13.2.2 normalize-path: 3.0.0 - schema-utils: 4.2.0 + schema-utils: 4.3.0 serialize-javascript: 6.0.2 - webpack: 5.91.0 + webpack: 5.97.1 - core-js-compat@3.37.0: + core-js-compat@3.40.0: dependencies: - browserslist: 4.23.0 + browserslist: 4.24.4 - core-js-pure@3.37.0: {} + core-js-pure@3.40.0: {} - core-js@3.37.0: {} + core-js@3.40.0: {} core-util-is@1.0.3: {} @@ -10359,16 +12113,16 @@ snapshots: optionalDependencies: typescript: 5.2.2 - cpy@11.0.1: + cpy@11.1.0: dependencies: copy-file: 11.0.0 - globby: 13.2.2 + globby: 14.0.2 junk: 4.0.1 - micromatch: 4.0.5 - p-filter: 3.0.0 - p-map: 6.0.0 + micromatch: 4.0.8 + p-filter: 4.1.0 + p-map: 7.0.3 - cross-spawn@6.0.5: + cross-spawn@6.0.6: dependencies: nice-try: 1.0.5 path-key: 2.0.1 @@ -10376,7 +12130,7 @@ snapshots: shebang-command: 1.2.0 which: 1.3.1 - cross-spawn@7.0.3: + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 @@ -10386,35 +12140,55 @@ snapshots: dependencies: type-fest: 1.4.0 - css-declaration-sorter@7.2.0(postcss@8.4.38): + crypto-random-string@5.0.0: + dependencies: + type-fest: 2.19.0 + + css-blank-pseudo@7.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + css-declaration-sorter@7.2.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + css-has-pseudo@7.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.0.0) + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.91.0): + css-loader@6.11.0(webpack@5.97.1): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.0.5(postcss@8.4.38) - postcss-modules-scope: 3.2.0(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.1) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.1) + postcss-modules-scope: 3.2.1(postcss@8.5.1) + postcss-modules-values: 4.0.0(postcss@8.5.1) postcss-value-parser: 4.2.0 - semver: 7.6.0 + semver: 7.6.3 optionalDependencies: - webpack: 5.91.0 + webpack: 5.97.1 - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.91.0): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.97.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 - cssnano: 6.1.2(postcss@8.4.38) + cssnano: 6.1.2(postcss@8.5.1) jest-worker: 29.7.0 - postcss: 8.4.38 - schema-utils: 4.2.0 + postcss: 8.5.1 + schema-utils: 4.3.0 serialize-javascript: 6.0.2 - webpack: 5.91.0 + webpack: 5.97.1 optionalDependencies: clean-css: 5.3.3 + css-prefers-color-scheme@10.0.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -10428,77 +12202,79 @@ snapshots: boolbase: 1.0.0 css-what: 6.1.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 nth-check: 2.1.1 css-tree@2.2.1: dependencies: mdn-data: 2.0.28 - source-map-js: 1.2.0 + source-map-js: 1.2.1 css-tree@2.3.1: dependencies: mdn-data: 2.0.30 - source-map-js: 1.2.0 + source-map-js: 1.2.1 css-what@6.1.0: {} + cssdb@8.2.3: {} + cssesc@3.0.0: {} - cssnano-preset-advanced@6.1.2(postcss@8.4.38): - dependencies: - autoprefixer: 10.4.19(postcss@8.4.38) - browserslist: 4.23.0 - cssnano-preset-default: 6.1.2(postcss@8.4.38) - postcss: 8.4.38 - postcss-discard-unused: 6.0.5(postcss@8.4.38) - postcss-merge-idents: 6.0.3(postcss@8.4.38) - postcss-reduce-idents: 6.0.3(postcss@8.4.38) - postcss-zindex: 6.0.2(postcss@8.4.38) - - cssnano-preset-default@6.1.2(postcss@8.4.38): - dependencies: - browserslist: 4.23.0 - css-declaration-sorter: 7.2.0(postcss@8.4.38) - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 - postcss-calc: 9.0.1(postcss@8.4.38) - postcss-colormin: 6.1.0(postcss@8.4.38) - postcss-convert-values: 6.1.0(postcss@8.4.38) - postcss-discard-comments: 6.0.2(postcss@8.4.38) - postcss-discard-duplicates: 6.0.3(postcss@8.4.38) - postcss-discard-empty: 6.0.3(postcss@8.4.38) - postcss-discard-overridden: 6.0.2(postcss@8.4.38) - postcss-merge-longhand: 6.0.5(postcss@8.4.38) - postcss-merge-rules: 6.1.1(postcss@8.4.38) - postcss-minify-font-values: 6.1.0(postcss@8.4.38) - postcss-minify-gradients: 6.0.3(postcss@8.4.38) - postcss-minify-params: 6.1.0(postcss@8.4.38) - postcss-minify-selectors: 6.0.4(postcss@8.4.38) - postcss-normalize-charset: 6.0.2(postcss@8.4.38) - postcss-normalize-display-values: 6.0.2(postcss@8.4.38) - postcss-normalize-positions: 6.0.2(postcss@8.4.38) - postcss-normalize-repeat-style: 6.0.2(postcss@8.4.38) - postcss-normalize-string: 6.0.2(postcss@8.4.38) - postcss-normalize-timing-functions: 6.0.2(postcss@8.4.38) - postcss-normalize-unicode: 6.1.0(postcss@8.4.38) - postcss-normalize-url: 6.0.2(postcss@8.4.38) - postcss-normalize-whitespace: 6.0.2(postcss@8.4.38) - postcss-ordered-values: 6.0.2(postcss@8.4.38) - postcss-reduce-initial: 6.1.0(postcss@8.4.38) - postcss-reduce-transforms: 6.0.2(postcss@8.4.38) - postcss-svgo: 6.0.3(postcss@8.4.38) - postcss-unique-selectors: 6.0.4(postcss@8.4.38) - - cssnano-utils@4.0.2(postcss@8.4.38): - dependencies: - postcss: 8.4.38 - - cssnano@6.1.2(postcss@8.4.38): - dependencies: - cssnano-preset-default: 6.1.2(postcss@8.4.38) - lilconfig: 3.1.1 - postcss: 8.4.38 + cssnano-preset-advanced@6.1.2(postcss@8.5.1): + dependencies: + autoprefixer: 10.4.20(postcss@8.5.1) + browserslist: 4.24.4 + cssnano-preset-default: 6.1.2(postcss@8.5.1) + postcss: 8.5.1 + postcss-discard-unused: 6.0.5(postcss@8.5.1) + postcss-merge-idents: 6.0.3(postcss@8.5.1) + postcss-reduce-idents: 6.0.3(postcss@8.5.1) + postcss-zindex: 6.0.2(postcss@8.5.1) + + cssnano-preset-default@6.1.2(postcss@8.5.1): + dependencies: + browserslist: 4.24.4 + css-declaration-sorter: 7.2.0(postcss@8.5.1) + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 + postcss-calc: 9.0.1(postcss@8.5.1) + postcss-colormin: 6.1.0(postcss@8.5.1) + postcss-convert-values: 6.1.0(postcss@8.5.1) + postcss-discard-comments: 6.0.2(postcss@8.5.1) + postcss-discard-duplicates: 6.0.3(postcss@8.5.1) + postcss-discard-empty: 6.0.3(postcss@8.5.1) + postcss-discard-overridden: 6.0.2(postcss@8.5.1) + postcss-merge-longhand: 6.0.5(postcss@8.5.1) + postcss-merge-rules: 6.1.1(postcss@8.5.1) + postcss-minify-font-values: 6.1.0(postcss@8.5.1) + postcss-minify-gradients: 6.0.3(postcss@8.5.1) + postcss-minify-params: 6.1.0(postcss@8.5.1) + postcss-minify-selectors: 6.0.4(postcss@8.5.1) + postcss-normalize-charset: 6.0.2(postcss@8.5.1) + postcss-normalize-display-values: 6.0.2(postcss@8.5.1) + postcss-normalize-positions: 6.0.2(postcss@8.5.1) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.1) + postcss-normalize-string: 6.0.2(postcss@8.5.1) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.1) + postcss-normalize-unicode: 6.1.0(postcss@8.5.1) + postcss-normalize-url: 6.0.2(postcss@8.5.1) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.1) + postcss-ordered-values: 6.0.2(postcss@8.5.1) + postcss-reduce-initial: 6.1.0(postcss@8.5.1) + postcss-reduce-transforms: 6.0.2(postcss@8.5.1) + postcss-svgo: 6.0.3(postcss@8.5.1) + postcss-unique-selectors: 6.0.4(postcss@8.5.1) + + cssnano-utils@4.0.2(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + cssnano@6.1.2(postcss@8.5.1): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.1) + lilconfig: 3.1.3 + postcss: 8.5.1 csso@5.0.5: dependencies: @@ -10506,23 +12282,23 @@ snapshots: csstype@3.1.3: {} - data-view-buffer@1.0.1: + data-view-buffer@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-length@1.0.1: + data-view-byte-length@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 - data-view-byte-offset@1.0.0: + data-view-byte-offset@1.0.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - is-data-view: 1.0.1 + is-data-view: 1.0.2 debounce-fn@5.1.2: dependencies: @@ -10534,9 +12310,13 @@ snapshots: dependencies: ms: 2.0.0 - debug@4.3.4(supports-color@8.1.1): + debug@4.3.4: dependencies: ms: 2.1.2 + + debug@4.4.0(supports-color@8.1.1): + dependencies: + ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 @@ -10556,6 +12336,18 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@3.0.0: + dependencies: + bplist-parser: 0.2.0 + untildify: 4.0.0 + + default-browser@4.0.0: + dependencies: + bundle-name: 3.0.0 + default-browser-id: 3.0.0 + execa: 7.2.0 + titleize: 3.0.0 + default-gateway@6.0.3: dependencies: execa: 5.1.1 @@ -10564,12 +12356,14 @@ snapshots: define-data-property@1.1.4: dependencies: - es-define-property: 1.0.0 + es-define-property: 1.0.1 es-errors: 1.3.0 - gopd: 1.0.1 + gopd: 1.2.0 define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -10589,17 +12383,17 @@ snapshots: depcheck@1.4.7: dependencies: - '@babel/parser': 7.24.5 - '@babel/traverse': 7.24.5 - '@vue/compiler-sfc': 3.4.27 + '@babel/parser': 7.26.5 + '@babel/traverse': 7.26.5 + '@vue/compiler-sfc': 3.5.13 callsite: 1.0.0 camelcase: 6.3.0 cosmiconfig: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) deps-regex: 0.2.0 findup-sync: 5.0.0 - ignore: 5.3.1 - is-core-module: 2.13.1 + ignore: 5.3.2 + is-core-module: 2.16.1 js-yaml: 3.14.1 json5: 2.2.3 lodash: 4.17.21 @@ -10608,9 +12402,9 @@ snapshots: please-upgrade-node: 3.2.0 readdirp: 3.6.0 require-package-name: 2.0.1 - resolve: 1.22.8 + resolve: 1.22.10 resolve-from: 5.0.0 - semver: 7.6.0 + semver: 7.6.3 yargs: 16.2.0 transitivePeerDependencies: - supports-color @@ -10636,10 +12430,10 @@ snapshots: transitivePeerDependencies: - supports-color - detect-port@1.5.1: + detect-port@1.6.1: dependencies: address: 1.2.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -10647,8 +12441,6 @@ snapshots: dependencies: dequal: 2.0.3 - diff@5.0.0: {} - diff@5.2.0: {} dir-glob@3.0.1: @@ -10700,7 +12492,7 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 - domutils@3.1.0: + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -10709,7 +12501,7 @@ snapshots: dot-case@3.0.4: dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.1 dot-prop@6.0.1: dependencies: @@ -10719,6 +12511,16 @@ snapshots: dependencies: type-fest: 2.19.0 + dot-prop@9.0.0: + dependencies: + type-fest: 4.33.0 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + duplexer@0.1.2: {} eastasianwidth@0.2.0: {} @@ -10729,9 +12531,9 @@ snapshots: dependencies: encoding: 0.1.13 - electron-to-chromium@1.4.757: {} + electron-to-chromium@1.5.84: {} - emoji-regex@10.3.0: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} @@ -10741,20 +12543,22 @@ snapshots: emojis-list@3.0.0: {} - emoticon@4.0.1: {} + emoticon@4.1.0: {} encodeurl@1.0.2: {} + encodeurl@2.0.0: {} + encoding@0.1.13: dependencies: iconv-lite: 0.6.3 - enhanced-resolve@5.16.0: + enhanced-resolve@5.18.0: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - entail@2.1.2: + entail@2.2.1: dependencies: dequal: 2.0.3 globby: 13.1.4 @@ -10768,84 +12572,104 @@ snapshots: env-paths@3.0.0: {} + environment@1.1.0: {} + err-code@3.0.1: {} error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.3: + es-abstract@1.23.9: dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - data-view-buffer: 1.0.1 - data-view-byte-length: 1.0.1 - data-view-byte-offset: 1.0.0 - es-define-property: 1.0.0 + call-bind: 1.0.8 + call-bound: 1.0.3 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-set-tostringtag: 2.0.3 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.6 - get-intrinsic: 1.2.4 - get-symbol-description: 1.0.2 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 globalthis: 1.0.4 - gopd: 1.0.1 + gopd: 1.2.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.2.0 + has-symbols: 1.1.0 hasown: 2.0.2 - internal-slot: 1.0.7 - is-array-buffer: 3.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 is-callable: 1.2.7 - is-data-view: 1.0.1 - is-negative-zero: 2.0.3 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 - is-typed-array: 1.1.13 - is-weakref: 1.0.2 - object-inspect: 1.13.1 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.0 + math-intrinsics: 1.1.0 + object-inspect: 1.13.3 object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.2 - safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.9 - string.prototype.trimend: 1.0.8 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.2 - typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.6 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.15 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.18 - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 + es-define-property@1.0.1: {} es-errors@1.3.0: {} - es-module-lexer@1.5.2: {} + es-module-lexer@1.6.0: {} - es-object-atoms@1.0.0: + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 - es-set-tostringtag@2.0.3: + es-set-tostringtag@2.1.0: dependencies: - get-intrinsic: 1.2.4 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 has-tostringtag: 1.0.2 hasown: 2.0.2 - es-to-primitive@1.2.1: + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.14.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.2 esbuild-plugin-wasm@1.1.0: {} @@ -10874,7 +12698,35 @@ snapshots: '@esbuild/win32-ia32': 0.19.5 '@esbuild/win32-x64': 0.19.5 - escalade@3.1.2: {} + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + + escalade@3.2.0: {} escape-goat@4.0.0: {} @@ -10886,17 +12738,17 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-plugin-jsdoc@46.10.1(eslint@8.57.0): + eslint-plugin-jsdoc@46.10.1(eslint@8.57.1): dependencies: '@es-joy/jsdoccomment': 0.41.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) escape-string-regexp: 4.0.0 - eslint: 8.57.0 - esquery: 1.5.0 + eslint: 8.57.1 + esquery: 1.6.0 is-builtin-module: 3.2.1 - semver: 7.6.0 + semver: 7.6.3 spdx-expression-parse: 4.0.0 transitivePeerDependencies: - supports-color @@ -10913,26 +12765,26 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint@8.57.0: + eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 + '@ungap/structured-clone': 1.2.1 ajv: 6.12.6 chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + cross-spawn: 7.0.6 + debug: 4.4.0(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -10940,7 +12792,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -10958,13 +12810,13 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -10978,7 +12830,7 @@ snapshots: estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 estree-util-build-jsx@3.0.1: dependencies: @@ -10989,27 +12841,31 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.6 + devlop: 1.1.0 + estree-util-to-js@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 - astring: 1.8.6 + astring: 1.9.0 source-map: 0.7.4 - estree-util-value-to-estree@3.1.1: + estree-util-value-to-estree@3.2.1: dependencies: - '@types/estree': 1.0.5 - is-plain-obj: 4.1.0 + '@types/estree': 1.0.6 estree-util-visit@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 estree-walker@2.0.2: {} estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 esutils@2.0.3: {} @@ -11019,7 +12875,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 require-like: 0.1.2 eventemitter3@4.0.7: {} @@ -11034,7 +12890,7 @@ snapshots: execa@5.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 6.0.1 human-signals: 2.1.0 is-stream: 2.0.1 @@ -11046,7 +12902,7 @@ snapshots: execa@7.2.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 6.0.1 human-signals: 4.3.1 is-stream: 3.0.0 @@ -11058,7 +12914,7 @@ snapshots: execa@8.0.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 8.0.1 human-signals: 5.0.0 is-stream: 3.0.0 @@ -11074,34 +12930,34 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 - express@4.19.2: + express@4.21.2: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.6.0 + cookie: 0.7.1 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: 1.6.18 @@ -11116,27 +12972,31 @@ snapshots: extend@3.0.2: {} + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} - fast-glob@3.3.2: + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} - fast-url-parser@1.1.3: - dependencies: - punycode: 1.4.1 + fast-uri@3.0.6: {} - fastq@1.17.1: + fastq@1.18.0: dependencies: reusify: 1.0.4 @@ -11154,26 +13014,34 @@ snapshots: fflate@0.8.2: {} + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.91.0): + file-loader@6.2.0(webpack@5.97.1): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.91.0 + webpack: 5.97.1 + + files-from-path@1.1.1: + dependencies: + graceful-fs: 4.2.11 filesize@8.0.7: {} - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - finalhandler@1.2.0: + finalhandler@1.3.1: dependencies: debug: 2.6.9 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 @@ -11205,20 +13073,20 @@ snapshots: dependencies: detect-file: 1.0.0 is-glob: 4.0.3 - micromatch: 4.0.5 + micromatch: 4.0.8 resolve-dir: 1.0.1 flat-cache@3.2.0: dependencies: - flatted: 3.3.1 + flatted: 3.3.2 keyv: 4.5.4 rimraf: 3.0.2 flat@5.0.2: {} - flatted@3.3.1: {} + flatted@3.3.2: {} - follow-redirects@1.15.6: {} + follow-redirects@1.15.9: {} for-each@0.3.3: dependencies: @@ -11226,17 +13094,17 @@ snapshots: foreground-child@2.0.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 3.0.7 - foreground-child@3.2.1: + foreground-child@3.3.0: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.0)(typescript@5.2.2)(webpack@5.91.0): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.2.2)(webpack@5.97.1): dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.26.2 '@types/json-schema': 7.0.15 chalk: 4.1.2 chokidar: 3.6.0 @@ -11247,12 +13115,12 @@ snapshots: memfs: 3.5.3 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.6.0 + semver: 7.6.3 tapable: 1.1.3 typescript: 5.2.2 - webpack: 5.91.0 + webpack: 5.97.1 optionalDependencies: - eslint: 8.57.0 + eslint: 8.57.1 form-data-encoder@2.1.4: {} @@ -11266,7 +13134,7 @@ snapshots: fresh@0.5.2: {} - fs-extra@11.2.0: + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 @@ -11288,12 +13156,14 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.6: + function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 define-properties: 1.2.1 - es-abstract: 1.23.3 functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 functions-have-names@1.2.3: {} @@ -11301,27 +13171,41 @@ snapshots: get-caller-file@2.0.5: {} - get-intrinsic@1.2.4: + get-east-asian-width@1.3.0: {} + + get-intrinsic@1.2.7: dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 es-errors: 1.3.0 + es-object-atoms: 1.1.1 function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 hasown: 2.0.2 + math-intrinsics: 1.1.0 get-iterator@1.0.2: {} get-own-enumerable-property-symbols@3.0.2: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stdin@4.0.1: {} + get-stream@6.0.1: {} get-stream@8.0.1: {} - get-symbol-description@1.0.2: + get-symbol-description@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - get-intrinsic: 1.2.4 + get-intrinsic: 1.2.7 github-slugger@1.5.0: {} @@ -11337,11 +13221,11 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.2.1 + foreground-child: 3.3.0 jackspeak: 3.4.3 - minimatch: 9.0.4 + minimatch: 9.0.5 minipass: 7.1.2 - package-json-from-dist: 1.0.0 + package-json-from-dist: 1.0.1 path-scurry: 1.11.1 glob@7.2.3: @@ -11358,9 +13242,13 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.0.1 + minimatch: 5.1.6 once: 1.4.0 + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + global-dirs@3.0.1: dependencies: ini: 2.0.0 @@ -11398,45 +13286,43 @@ snapshots: globalthis@1.0.4: dependencies: define-properties: 1.2.1 - gopd: 1.0.1 + gopd: 1.2.0 globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 + fast-glob: 3.3.3 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 globby@13.1.4: dependencies: dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 + fast-glob: 3.3.3 + ignore: 5.3.2 merge2: 1.4.1 slash: 4.0.0 globby@13.2.2: dependencies: dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 + fast-glob: 3.3.3 + ignore: 5.3.2 merge2: 1.4.1 slash: 4.0.0 - globby@14.0.1: + globby@14.0.2: dependencies: '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.2 - ignore: 5.3.1 + fast-glob: 3.3.3 + ignore: 5.3.2 path-type: 5.0.0 slash: 5.1.0 unicorn-magic: 0.1.0 - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.4 + gopd@1.2.0: {} got@12.6.1: dependencies: @@ -11472,7 +13358,7 @@ snapshots: hamt-sharding@3.0.6: dependencies: sparse-array: 1.3.2 - uint8arrays: 5.0.3 + uint8arrays: 5.1.0 handle-thing@2.0.1: {} @@ -11483,9 +13369,14 @@ snapshots: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.17.4 + uglify-js: 3.19.3 + + has-ansi@1.0.3: + dependencies: + ansi-regex: 1.1.1 + get-stdin: 4.0.1 - has-bigints@1.0.2: {} + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -11493,15 +13384,17 @@ snapshots: has-property-descriptors@1.0.2: dependencies: - es-define-property: 1.0.0 + es-define-property: 1.0.1 - has-proto@1.0.3: {} + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 - has-symbols@1.0.3: {} + has-symbols@1.1.0: {} has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 + has-symbols: 1.1.0 has-yarn@3.0.0: {} @@ -11509,40 +13402,40 @@ snapshots: dependencies: function-bind: 1.1.2 - hast-util-from-parse5@8.0.1: + hast-util-from-parse5@8.0.2: dependencies: '@types/hast': 3.0.4 - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 devlop: 1.1.0 - hastscript: 8.0.0 + hastscript: 9.0.0 property-information: 6.5.0 - vfile: 6.0.1 - vfile-location: 5.0.2 + vfile: 6.0.3 + vfile-location: 5.0.3 web-namespaces: 2.0.1 hast-util-parse-selector@4.0.0: dependencies: '@types/hast': 3.0.4 - hast-util-raw@9.0.3: + hast-util-raw@9.1.0: dependencies: '@types/hast': 3.0.4 - '@types/unist': 3.0.2 - '@ungap/structured-clone': 1.2.0 - hast-util-from-parse5: 8.0.1 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.2.1 + hast-util-from-parse5: 8.0.2 hast-util-to-parse5: 8.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.1.0 - parse5: 7.1.2 + mdast-util-to-hast: 13.2.0 + parse5: 7.2.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 web-namespaces: 2.0.1 zwitch: 2.0.4 - hast-util-to-estree@3.1.0: + hast-util-to-estree@3.1.1: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 @@ -11550,32 +13443,32 @@ snapshots: estree-util-attach-comments: 3.0.0 estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 property-information: 6.5.0 space-separated-tokens: 2.0.2 - style-to-object: 0.4.4 + style-to-object: 1.0.8 unist-util-position: 5.0.0 zwitch: 2.0.4 transitivePeerDependencies: - supports-color - hast-util-to-jsx-runtime@2.3.0: + hast-util-to-jsx-runtime@2.3.2: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@types/hast': 3.0.4 - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 property-information: 6.5.0 space-separated-tokens: 2.0.2 - style-to-object: 1.0.6 + style-to-object: 1.0.8 unist-util-position: 5.0.0 vfile-message: 4.0.2 transitivePeerDependencies: @@ -11595,7 +13488,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 - hastscript@8.0.0: + hastscript@9.0.0: dependencies: '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 @@ -11605,9 +13498,11 @@ snapshots: he@1.2.0: {} + highlight.js@10.7.3: {} + history@4.10.1: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.3.3 @@ -11643,7 +13538,7 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.31.0 + terser: 5.37.0 html-minifier-terser@7.2.0: dependencies: @@ -11653,13 +13548,13 @@ snapshots: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.31.0 + terser: 5.37.0 html-tags@3.3.1: {} html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.0(webpack@5.91.0): + html-webpack-plugin@5.6.3(webpack@5.97.1): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -11667,7 +13562,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.91.0 + webpack: 5.97.1 htmlparser2@6.1.0: dependencies: @@ -11680,7 +13575,7 @@ snapshots: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 entities: 4.5.0 http-cache-semantics@4.1.1: {} @@ -11702,15 +13597,15 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - http-parser-js@0.5.8: {} + http-parser-js@0.5.9: {} - http-proxy-middleware@2.0.6(@types/express@4.17.21): + http-proxy-middleware@2.0.7(@types/express@4.17.21): dependencies: - '@types/http-proxy': 1.17.14 + '@types/http-proxy': 1.17.15 http-proxy: 1.18.1 is-glob: 4.0.3 is-plain-obj: 3.0.0 - micromatch: 4.0.5 + micromatch: 4.0.8 optionalDependencies: '@types/express': 4.17.21 transitivePeerDependencies: @@ -11719,7 +13614,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.6 + follow-redirects: 1.15.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -11747,15 +13642,15 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.4.38): + icss-utils@5.1.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 ieee754@1.2.1: {} - ignore@5.3.1: {} + ignore@5.3.2: {} - image-size@1.1.1: + image-size@1.2.0: dependencies: queue: 6.0.2 @@ -11772,9 +13667,7 @@ snapshots: indent-string@4.0.0: {} - indent-string@5.0.0: {} - - infima@0.2.0-alpha.43: {} + infima@0.2.0-alpha.45: {} inflight@1.0.6: dependencies: @@ -11789,9 +13682,9 @@ snapshots: ini@2.0.0: {} - inline-style-parser@0.1.1: {} + ini@4.1.1: {} - inline-style-parser@0.2.3: {} + inline-style-parser@0.2.4: {} interface-blockstore@4.0.1: dependencies: @@ -11800,11 +13693,11 @@ snapshots: interface-store@3.0.4: {} - internal-slot@1.0.7: + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 - side-channel: 1.0.6 + side-channel: 1.1.0 interpret@1.4.0: {} @@ -11818,8 +13711,8 @@ snapshots: ipfs-unixfs-exporter@10.0.1: dependencies: - '@ipld/dag-cbor': 9.2.0 - '@ipld/dag-pb': 4.1.0 + '@ipld/dag-cbor': 9.2.2 + '@ipld/dag-pb': 4.1.3 '@multiformats/murmur3': 2.1.8 err-code: 3.0.1 hamt-sharding: 3.0.6 @@ -11827,7 +13720,7 @@ snapshots: ipfs-unixfs: 9.0.1 it-last: 2.0.1 it-map: 2.0.1 - it-parallel: 3.0.7 + it-parallel: 3.0.8 it-pipe: 2.0.5 it-pushable: 3.2.3 multiformats: 11.0.2 @@ -11837,7 +13730,7 @@ snapshots: ipfs-unixfs@9.0.1: dependencies: err-code: 3.0.1 - protobufjs: 7.2.6 + protobufjs: 7.4.0 ipfs-utils@9.0.14(encoding@0.1.13): dependencies: @@ -11852,8 +13745,8 @@ snapshots: it-glob: 1.0.2 it-to-stream: 1.0.0 merge-options: 3.0.4 - nanoid: 3.3.7 - native-fetch: 3.0.0(node-fetch@2.7.0(encoding@0.1.13)) + nanoid: 3.3.8 + native-fetch: 3.0.0(node-fetch@2.7.0) node-fetch: 2.7.0(encoding@0.1.13) react-native-fetch-api: 3.0.0 stream-to-it: 0.2.4 @@ -11867,29 +13760,37 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-arguments@1.1.1: + is-arguments@1.2.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 has-tostringtag: 1.0.2 - is-array-buffer@3.0.4: + is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 is-arrayish@0.2.1: {} - is-bigint@1.0.4: + is-async-function@2.1.0: dependencies: - has-bigints: 1.0.2 + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - is-boolean-object@1.1.2: + is-boolean-object@1.2.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 has-tostringtag: 1.0.2 is-builtin-module@3.2.1: @@ -11902,35 +13803,47 @@ snapshots: dependencies: ci-info: 3.9.0 - is-core-module@2.13.1: + is-core-module@2.16.1: dependencies: hasown: 2.0.2 - is-data-view@1.0.1: + is-data-view@1.0.2: dependencies: - is-typed-array: 1.1.13 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + is-typed-array: 1.1.15 - is-date-object@1.0.5: + is-date-object@1.1.0: dependencies: + call-bound: 1.0.3 has-tostringtag: 1.0.2 is-decimal@2.0.1: {} is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-electron@2.2.2: {} is-extendable@0.1.1: {} is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.3 + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@4.0.0: {} - is-generator-function@1.0.10: + is-generator-function@1.1.0: dependencies: + call-bound: 1.0.3 + get-proto: 1.0.1 has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 is-glob@4.0.3: dependencies: @@ -11938,24 +13851,36 @@ snapshots: is-hexadecimal@2.0.1: {} + is-in-ci@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-installed-globally@0.4.0: dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + is-interactive@2.0.0: {} + is-map@2.0.3: {} + is-nan@1.3.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - is-negative-zero@2.0.3: {} - is-npm@6.0.0: {} - is-number-object@1.0.7: + is-number-object@1.1.1: dependencies: + call-bound: 1.0.3 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -11968,6 +13893,8 @@ snapshots: is-path-inside@3.0.3: {} + is-path-inside@4.0.0: {} + is-plain-obj@2.1.0: {} is-plain-obj@3.0.0: {} @@ -11978,40 +13905,43 @@ snapshots: dependencies: isobject: 3.0.1 - is-reference@3.0.2: - dependencies: - '@types/estree': 1.0.5 - - is-regex@1.1.4: + is-regex@1.2.1: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 + gopd: 1.2.0 has-tostringtag: 1.0.2 + hasown: 2.0.2 is-regexp@1.0.0: {} is-root@2.1.0: {} - is-shared-array-buffer@1.0.3: + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 is-stream@2.0.1: {} is-stream@3.0.0: {} - is-string@1.0.7: + is-string@1.1.1: dependencies: + call-bound: 1.0.3 has-tostringtag: 1.0.2 is-subset@0.1.1: {} - is-symbol@1.0.4: + is-symbol@1.1.1: dependencies: - has-symbols: 1.0.3 + call-bound: 1.0.3 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 - is-typed-array@1.1.13: + is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.15 + which-typed-array: 1.1.18 is-typedarray@1.0.0: {} @@ -12019,9 +13949,16 @@ snapshots: is-unicode-supported@1.3.0: {} - is-weakref@1.0.2: + is-weakmap@2.0.2: {} + + is-weakref@1.1.0: + dependencies: + call-bound: 1.0.3 + + is-weakset@2.0.4: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 is-windows@1.0.2: {} @@ -12077,7 +14014,7 @@ snapshots: dependencies: it-pushable: 3.2.3 - it-parallel@3.0.7: + it-parallel@3.0.8: dependencies: p-defer: 4.0.1 @@ -12113,7 +14050,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.10 + '@types/node': 20.17.14 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -12121,20 +14058,20 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 20.12.10 + '@types/node': 20.17.14 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jiti@1.21.0: {} + jiti@1.21.7: {} - joi@17.13.1: + joi@17.13.3: dependencies: '@hapi/hoek': 9.3.0 '@hapi/topo': 5.1.0 @@ -12155,9 +14092,9 @@ snapshots: jsdoc-type-pratt-parser@4.0.0: {} - jsesc@0.5.0: {} + jsesc@3.0.2: {} - jsesc@2.5.2: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -12175,7 +14112,7 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.2.1: {} + jsonc-parser@3.3.1: {} jsonfile@6.1.0: dependencies: @@ -12197,14 +14134,20 @@ snapshots: kleur@4.1.5: {} + ky@1.7.4: {} + latest-version@7.0.0: dependencies: package-json: 8.1.1 - launch-editor@2.6.1: + latest-version@9.0.0: + dependencies: + package-json: 10.0.1 + + launch-editor@2.9.1: dependencies: - picocolors: 1.0.0 - shell-quote: 1.8.1 + picocolors: 1.1.1 + shell-quote: 1.8.2 leven@3.1.0: {} @@ -12215,7 +14158,7 @@ snapshots: lilconfig@2.1.0: {} - lilconfig@3.1.1: {} + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -12223,7 +14166,7 @@ snapshots: dependencies: chalk: 5.3.0 commander: 11.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 execa: 7.2.0 lilconfig: 2.1.0 listr2: 6.6.1 @@ -12241,7 +14184,7 @@ snapshots: colorette: 2.0.20 eventemitter3: 5.0.1 log-update: 5.0.1 - rfdc: 1.3.1 + rfdc: 1.4.1 wrap-ansi: 8.1.0 load-json-file@4.0.0: @@ -12259,7 +14202,7 @@ snapshots: emojis-list: 3.0.0 json5: 2.2.3 - loader-utils@3.2.1: {} + loader-utils@3.3.1: {} locate-path@3.0.0: dependencies: @@ -12293,7 +14236,7 @@ snapshots: log-symbols@5.1.0: dependencies: - chalk: 5.3.0 + chalk: 5.4.1 is-unicode-supported: 1.3.0 log-update@5.0.1: @@ -12304,7 +14247,7 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 8.1.0 - long@5.2.3: {} + long@5.2.4: {} longest-streak@3.1.0: {} @@ -12314,7 +14257,7 @@ snapshots: lower-case@2.0.2: dependencies: - tslib: 2.6.2 + tslib: 2.8.1 lowercase-keys@3.0.0: {} @@ -12324,33 +14267,34 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - lunr@2.3.9: {} - magic-string@0.30.10: + magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 make-dir@4.0.0: dependencies: - semver: 7.6.0 + semver: 7.6.3 markdown-extensions@2.0.0: {} - markdown-table@3.0.3: {} + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 + + markdown-table@3.0.4: {} - marked-terminal@6.2.0(marked@9.1.6): + marked-terminal@7.2.1(marked@9.1.6): dependencies: - ansi-escapes: 6.2.1 - cardinal: 2.1.1 - chalk: 5.3.0 - cli-table3: 0.6.4 + ansi-escapes: 7.0.0 + ansi-regex: 6.1.0 + chalk: 5.4.1 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 marked: 9.1.6 - node-emoji: 2.1.3 - supports-hyperlinks: 3.0.0 + node-emoji: 2.2.0 + supports-hyperlinks: 3.1.0 marked@4.3.0: {} @@ -12360,135 +14304,136 @@ snapshots: dependencies: '@arr/every': 1.0.1 + math-intrinsics@1.1.0: {} + mdast-util-directive@3.0.0: dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - parse-entities: 4.0.1 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 stringify-entities: 4.0.4 unist-util-visit-parents: 6.0.1 transitivePeerDependencies: - supports-color - mdast-util-find-and-replace@3.0.1: + mdast-util-find-and-replace@3.0.2: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - mdast-util-from-markdown@2.0.0: + mdast-util-from-markdown@2.0.2: dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 decode-named-character-reference: 1.0.2 devlop: 1.1.0 mdast-util-to-string: 4.0.0 - micromark: 4.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-decode-string: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark: 4.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color mdast-util-frontmatter@2.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 escape-string-regexp: 5.0.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 micromark-extension-frontmatter: 2.0.0 transitivePeerDependencies: - supports-color - mdast-util-gfm-autolink-literal@2.0.0: + mdast-util-gfm-autolink-literal@2.0.1: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.1 - micromark-util-character: 2.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 mdast-util-gfm-footnote@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - micromark-util-normalize-identifier: 2.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 transitivePeerDependencies: - supports-color mdast-util-gfm-strikethrough@2.0.0: dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-gfm-table@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - markdown-table: 3.0.3 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-gfm@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.0 - mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 mdast-util-gfm-footnote: 2.0.0 mdast-util-gfm-strikethrough: 2.0.0 mdast-util-gfm-table: 2.0.0 mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.0 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-mdx-expression@2.0.0: + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color - mdast-util-mdx-jsx@3.1.2: + mdast-util-mdx-jsx@3.2.0: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - parse-entities: 4.0.1 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 stringify-entities: 4.0.4 - unist-util-remove-position: 5.0.0 unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 transitivePeerDependencies: @@ -12496,11 +14441,11 @@ snapshots: mdast-util-mdx@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 - mdast-util-to-markdown: 2.1.0 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -12508,44 +14453,45 @@ snapshots: dependencies: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-phrasing@4.1.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 unist-util-is: 6.0.0 - mdast-util-to-hast@13.1.0: + mdast-util-to-hast@13.2.0: dependencies: '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - '@ungap/structured-clone': 1.2.0 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.1 devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.0 + micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.1 + vfile: 6.0.3 - mdast-util-to-markdown@2.1.0: + mdast-util-to-markdown@2.1.2: dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 longest-streak: 3.1.0 mdast-util-phrasing: 4.1.0 mdast-util-to-string: 4.0.0 - micromark-util-decode-string: 2.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 unist-util-visit: 5.0.0 zwitch: 2.0.4 mdast-util-to-string@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdn-data@2.0.28: {} @@ -12559,7 +14505,7 @@ snapshots: memorystream@0.3.1: {} - merge-descriptors@1.0.1: {} + merge-descriptors@1.0.3: {} merge-options@3.0.4: dependencies: @@ -12573,172 +14519,174 @@ snapshots: methods@1.1.2: {} - micromark-core-commonmark@2.0.1: + micromark-core-commonmark@2.0.2: dependencies: decode-named-character-reference: 1.0.2 devlop: 1.1.0 - micromark-factory-destination: 2.0.0 - micromark-factory-label: 2.0.0 - micromark-factory-space: 2.0.0 - micromark-factory-title: 2.0.0 - micromark-factory-whitespace: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-classify-character: 2.0.0 - micromark-util-html-tag-name: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-subtokenize: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-directive@3.0.0: + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.0.4 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-directive@3.0.2: dependencies: devlop: 1.1.0 - micromark-factory-space: 2.0.0 - micromark-factory-whitespace: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - parse-entities: 4.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + parse-entities: 4.0.2 micromark-extension-frontmatter@2.0.0: dependencies: fault: 2.0.1 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-extension-gfm-autolink-literal@2.0.0: + micromark-extension-gfm-autolink-literal@2.1.0: dependencies: - micromark-util-character: 2.1.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-extension-gfm-footnote@2.0.0: + micromark-extension-gfm-footnote@2.1.0: dependencies: devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-extension-gfm-strikethrough@2.0.0: + micromark-extension-gfm-strikethrough@2.1.0: dependencies: devlop: 1.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-classify-character: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-extension-gfm-table@2.0.0: + micromark-extension-gfm-table@2.1.1: dependencies: devlop: 1.1.0 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 micromark-extension-gfm-tagfilter@2.0.0: dependencies: - micromark-util-types: 2.0.0 + micromark-util-types: 2.0.1 - micromark-extension-gfm-task-list-item@2.0.1: + micromark-extension-gfm-task-list-item@2.1.0: dependencies: devlop: 1.1.0 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 micromark-extension-gfm@3.0.0: dependencies: - micromark-extension-gfm-autolink-literal: 2.0.0 - micromark-extension-gfm-footnote: 2.0.0 - micromark-extension-gfm-strikethrough: 2.0.0 - micromark-extension-gfm-table: 2.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.0.1 - micromark-util-combine-extensions: 2.0.0 - micromark-util-types: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.1 micromark-extension-mdx-expression@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 + micromark-factory-mdx-expression: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-extension-mdx-jsx@3.0.0: + micromark-extension-mdx-jsx@3.0.1: dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-factory-mdx-expression: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 vfile-message: 4.0.2 micromark-extension-mdx-md@2.0.0: dependencies: - micromark-util-types: 2.0.0 + micromark-util-types: 2.0.1 micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-util-character: 2.1.0 + micromark-core-commonmark: 2.0.2 + micromark-util-character: 2.1.1 micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 unist-util-position-from-estree: 2.0.0 vfile-message: 4.0.2 micromark-extension-mdxjs@3.0.0: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) micromark-extension-mdx-expression: 3.0.0 - micromark-extension-mdx-jsx: 3.0.0 + micromark-extension-mdx-jsx: 3.0.1 micromark-extension-mdx-md: 2.0.0 micromark-extension-mdxjs-esm: 3.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.1 - micromark-factory-destination@2.0.0: + micromark-factory-destination@2.0.1: dependencies: - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-factory-label@2.0.0: + micromark-factory-label@2.0.1: dependencies: devlop: 1.1.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-factory-mdx-expression@2.0.1: + micromark-factory-mdx-expression@2.0.2: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 devlop: 1.1.0 - micromark-util-character: 2.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 unist-util-position-from-estree: 2.0.0 vfile-message: 4.0.2 @@ -12747,136 +14695,143 @@ snapshots: micromark-util-character: 1.2.0 micromark-util-types: 1.1.0 - micromark-factory-space@2.0.0: + micromark-factory-space@2.0.1: dependencies: - micromark-util-character: 2.1.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.1 - micromark-factory-title@2.0.0: + micromark-factory-title@2.0.1: dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-factory-whitespace@2.0.0: + micromark-factory-whitespace@2.0.1: dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 micromark-util-character@1.2.0: dependencies: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 - micromark-util-character@2.1.0: + micromark-util-character@2.1.1: dependencies: - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-util-chunked@2.0.0: + micromark-util-chunked@2.0.1: dependencies: - micromark-util-symbol: 2.0.0 + micromark-util-symbol: 2.0.1 - micromark-util-classify-character@2.0.0: + micromark-util-classify-character@2.0.1: dependencies: - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 - micromark-util-combine-extensions@2.0.0: + micromark-util-combine-extensions@2.0.1: dependencies: - micromark-util-chunked: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.1 - micromark-util-decode-numeric-character-reference@2.0.1: + micromark-util-decode-numeric-character-reference@2.0.2: dependencies: - micromark-util-symbol: 2.0.0 + micromark-util-symbol: 2.0.1 - micromark-util-decode-string@2.0.0: + micromark-util-decode-string@2.0.1: dependencies: decode-named-character-reference: 1.0.2 - micromark-util-character: 2.1.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-symbol: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 - micromark-util-encode@2.0.0: {} + micromark-util-encode@2.0.1: {} micromark-util-events-to-acorn@2.0.2: dependencies: '@types/acorn': 4.0.6 - '@types/estree': 1.0.5 - '@types/unist': 3.0.2 + '@types/estree': 1.0.6 + '@types/unist': 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 vfile-message: 4.0.2 - micromark-util-html-tag-name@2.0.0: {} + micromark-util-html-tag-name@2.0.1: {} - micromark-util-normalize-identifier@2.0.0: + micromark-util-normalize-identifier@2.0.1: dependencies: - micromark-util-symbol: 2.0.0 + micromark-util-symbol: 2.0.1 - micromark-util-resolve-all@2.0.0: + micromark-util-resolve-all@2.0.1: dependencies: - micromark-util-types: 2.0.0 + micromark-util-types: 2.0.1 - micromark-util-sanitize-uri@2.0.0: + micromark-util-sanitize-uri@2.0.1: dependencies: - micromark-util-character: 2.1.0 - micromark-util-encode: 2.0.0 - micromark-util-symbol: 2.0.0 + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - micromark-util-subtokenize@2.0.1: + micromark-util-subtokenize@2.0.4: dependencies: devlop: 1.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 micromark-util-symbol@1.1.0: {} - micromark-util-symbol@2.0.0: {} + micromark-util-symbol@2.0.1: {} micromark-util-types@1.1.0: {} - micromark-util-types@2.0.0: {} + micromark-util-types@2.0.1: {} - micromark@4.0.0: + micromark@4.0.1: dependencies: '@types/debug': 4.1.12 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) decode-named-character-reference: 1.0.2 devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-subtokenize: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.0.4 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 transitivePeerDependencies: - supports-color micromatch@4.0.5: dependencies: - braces: 3.0.2 + braces: 3.0.3 + picomatch: 2.3.1 + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 picomatch: 2.3.1 mime-db@1.33.0: {} mime-db@1.52.0: {} + mime-db@1.53.0: {} + mime-types@2.1.18: dependencies: mime-db: 1.33.0 @@ -12895,11 +14850,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.9.0(webpack@5.91.0): + mini-css-extract-plugin@2.9.2(webpack@5.97.1): dependencies: - schema-utils: 4.2.0 + schema-utils: 4.3.0 tapable: 2.2.1 - webpack: 5.91.0 + webpack: 5.97.1 minimalistic-assert@1.0.1: {} @@ -12907,7 +14862,7 @@ snapshots: dependencies: brace-expansion: 1.1.11 - minimatch@5.0.1: + minimatch@5.1.6: dependencies: brace-expansion: 2.0.1 @@ -12919,7 +14874,7 @@ snapshots: dependencies: brace-expansion: 2.0.1 - minimatch@9.0.4: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -12927,27 +14882,27 @@ snapshots: minipass@7.1.2: {} - mocha@10.4.0: + mocha@10.8.2: dependencies: - ansi-colors: 4.1.1 + ansi-colors: 4.1.3 browser-stdout: 1.3.1 - chokidar: 3.5.3 - debug: 4.3.4(supports-color@8.1.1) - diff: 5.0.0 + chokidar: 3.6.0 + debug: 4.4.0(supports-color@8.1.1) + diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 - minimatch: 5.0.1 + minimatch: 5.1.6 ms: 2.1.3 - serialize-javascript: 6.0.0 + serialize-javascript: 6.0.2 strip-json-comments: 3.1.1 supports-color: 8.1.1 - workerpool: 6.2.1 + workerpool: 6.5.1 yargs: 16.2.0 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 yargs-unparser: 2.0.0 mri@1.2.0: {} @@ -12969,9 +14924,7 @@ snapshots: multiformats@12.1.3: {} - multiformats@13.1.0: {} - - multiformats@13.3.0: {} + multiformats@13.3.1: {} multimatch@5.0.0: dependencies: @@ -12983,11 +14936,19 @@ snapshots: murmurhash3js-revisited@3.0.0: {} - nanoid@3.3.7: {} + mute-stream@1.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.8: {} - nanoid@5.0.7: {} + nanoid@5.0.9: {} - native-fetch@3.0.0(node-fetch@2.7.0(encoding@0.1.13)): + native-fetch@3.0.0(node-fetch@2.7.0): dependencies: node-fetch: 2.7.0(encoding@0.1.13) @@ -12995,6 +14956,8 @@ snapshots: negotiator@0.6.3: {} + negotiator@0.6.4: {} + neo-async@2.6.2: {} nice-try@1.0.5: {} @@ -13002,17 +14965,17 @@ snapshots: nise@5.1.9: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/text-encoding': 0.7.2 + '@sinonjs/fake-timers': 11.3.1 + '@sinonjs/text-encoding': 0.7.3 just-extend: 6.2.0 - path-to-regexp: 6.2.2 + path-to-regexp: 6.3.0 no-case@3.0.4: dependencies: lower-case: 2.0.2 - tslib: 2.6.2 + tslib: 2.8.1 - node-emoji@2.1.3: + node-emoji@2.2.0: dependencies: '@sindresorhus/is': 4.6.0 char-regex: 1.0.2 @@ -13027,12 +14990,12 @@ snapshots: node-forge@1.3.1: {} - node-releases@2.0.14: {} + node-releases@2.0.19: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.8 + resolve: 1.22.10 semver: 5.7.2 validate-npm-package-license: 3.0.4 @@ -13046,12 +15009,12 @@ snapshots: dependencies: ansi-styles: 3.2.1 chalk: 2.4.2 - cross-spawn: 6.0.5 + cross-spawn: 6.0.6 memorystream: 0.3.1 minimatch: 3.1.2 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.8.1 + shell-quote: 1.8.2 string.prototype.padend: 3.1.6 npm-run-path@4.0.1: @@ -13068,22 +15031,30 @@ snapshots: dependencies: boolbase: 1.0.0 + null-loader@4.0.1(webpack@5.97.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.97.1 + object-assign@4.1.1: {} - object-inspect@1.13.1: {} + object-inspect@1.13.3: {} object-is@1.1.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 object-keys@1.1.1: {} - object.assign@4.1.5: + object.assign@4.1.7: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 define-properties: 1.2.1 - has-symbols: 1.0.3 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 object-keys: 1.1.1 obuf@1.1.2: {} @@ -13114,6 +15085,13 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + open@9.1.0: + dependencies: + default-browser: 4.0.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 2.2.0 + opener@1.5.2: {} optionator@0.9.4: @@ -13127,7 +15105,7 @@ snapshots: ora@7.0.1: dependencies: - chalk: 5.3.0 + chalk: 5.4.1 cli-cursor: 4.0.0 cli-spinners: 2.9.2 is-interactive: 2.0.0 @@ -13137,6 +15115,14 @@ snapshots: string-width: 6.1.0 strip-ansi: 7.1.0 + os-tmpdir@1.0.2: {} + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.2.7 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-cancelable@3.0.0: {} p-defer@3.0.0: {} @@ -13145,16 +15131,16 @@ snapshots: p-event@6.0.1: dependencies: - p-timeout: 6.1.2 + p-timeout: 6.1.4 p-fifo@1.0.0: dependencies: fast-fifo: 1.3.2 p-defer: 3.0.0 - p-filter@3.0.0: + p-filter@4.1.0: dependencies: - p-map: 5.5.0 + p-map: 7.0.3 p-limit@2.3.0: dependencies: @@ -13166,7 +15152,7 @@ snapshots: p-limit@4.0.0: dependencies: - yocto-queue: 1.0.0 + yocto-queue: 1.1.1 p-locate@3.0.0: dependencies: @@ -13184,12 +15170,10 @@ snapshots: dependencies: aggregate-error: 3.1.0 - p-map@5.5.0: - dependencies: - aggregate-error: 4.0.1 - p-map@6.0.0: {} + p-map@7.0.3: {} + p-queue@7.4.1: dependencies: eventemitter3: 5.0.1 @@ -13207,36 +15191,42 @@ snapshots: p-timeout@5.1.0: {} - p-timeout@6.1.2: {} + p-timeout@6.1.4: {} p-try@2.2.0: {} p-wait-for@5.0.2: dependencies: - p-timeout: 6.1.2 + p-timeout: 6.1.4 + + package-json-from-dist@1.0.1: {} - package-json-from-dist@1.0.0: {} + package-json@10.0.1: + dependencies: + ky: 1.7.4 + registry-auth-token: 5.0.3 + registry-url: 6.0.1 + semver: 7.6.3 package-json@8.1.1: dependencies: got: 12.6.1 - registry-auth-token: 5.0.2 + registry-auth-token: 5.0.3 registry-url: 6.0.1 - semver: 7.6.0 + semver: 7.6.3 param-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.1 parent-module@1.0.1: dependencies: callsites: 3.1.0 - parse-entities@4.0.1: + parse-entities@4.0.2: dependencies: - '@types/unist': 2.0.10 - character-entities: 2.0.2 + '@types/unist': 2.0.11 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 decode-named-character-reference: 1.0.2 @@ -13251,7 +15241,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.26.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -13260,12 +15250,20 @@ snapshots: parse-passwd@1.0.0: {} - parse5-htmlparser2-tree-adapter@7.0.0: + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 - parse5: 7.1.2 + parse5: 7.2.1 + + parse5@5.1.1: {} - parse5@7.1.2: + parse5@6.0.1: {} + + parse5@7.2.1: dependencies: entities: 4.5.0 @@ -13274,7 +15272,7 @@ snapshots: pascal-case@3.1.2: dependencies: no-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.1 path-browserify@1.0.1: {} @@ -13301,15 +15299,15 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@0.1.7: {} + path-to-regexp@0.1.12: {} - path-to-regexp@1.8.0: + path-to-regexp@1.9.0: dependencies: isarray: 0.0.1 - path-to-regexp@2.2.1: {} + path-to-regexp@3.3.0: {} - path-to-regexp@6.2.2: {} + path-to-regexp@6.3.0: {} path-type@3.0.0: dependencies: @@ -13319,13 +15317,7 @@ snapshots: path-type@5.0.0: {} - periscopic@3.1.0: - dependencies: - '@types/estree': 1.0.5 - estree-walker: 3.0.3 - is-reference: 3.0.2 - - picocolors@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -13353,20 +15345,20 @@ snapshots: c8: 8.0.1 camelcase: 8.0.0 chokidar: 3.6.0 - cpy: 11.0.1 + cpy: 11.1.0 esbuild: 0.19.5 esbuild-plugin-wasm: 1.1.0 events: 3.3.0 execa: 8.0.1 exit-hook: 4.0.0 - globby: 14.0.1 + globby: 14.0.2 kleur: 4.1.5 lilconfig: 2.1.0 lodash: 4.17.21 merge-options: 3.0.4 - nanoid: 5.0.7 + nanoid: 5.0.9 ora: 7.0.1 - p-timeout: 6.1.2 + p-timeout: 6.1.4 path-browserify: 1.0.1 playwright-core: 1.39.0 polka: 0.5.2 @@ -13380,7 +15372,7 @@ snapshots: tempy: 3.1.0 test-exclude: 6.0.0 util: 0.12.5 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 please-upgrade-node@3.2.0: dependencies: @@ -13393,221 +15385,438 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-calc@9.0.1(postcss@8.4.38): + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-calc@9.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-clamp@4.1.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-color-functional-notation@7.0.7(postcss@8.5.1): + dependencies: + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + + postcss-color-hex-alpha@10.0.0(postcss@8.5.1): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-color-rebeccapurple@10.0.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-colormin@6.1.0(postcss@8.4.38): + postcss-colormin@6.1.0(postcss@8.5.1): dependencies: - browserslist: 4.23.0 + browserslist: 4.24.4 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.4.38 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-convert-values@6.1.0(postcss@8.5.1): + dependencies: + browserslist: 4.24.4 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-custom-media@11.0.5(postcss@8.5.1): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + postcss: 8.5.1 + + postcss-custom-properties@14.0.4(postcss@8.5.1): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-convert-values@6.1.0(postcss@8.4.38): + postcss-custom-selectors@8.0.4(postcss@8.5.1): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.4(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-dir-pseudo-class@9.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-discard-comments@6.0.2(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-discard-duplicates@6.0.3(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-discard-empty@6.0.3(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-discard-overridden@6.0.2(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-discard-unused@6.0.5(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 + + postcss-double-position-gradients@6.0.0(postcss@8.5.1): dependencies: - browserslist: 4.23.0 - postcss: 8.4.38 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-discard-comments@6.0.2(postcss@8.4.38): + postcss-focus-visible@10.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-focus-within@9.0.1(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 - postcss-discard-duplicates@6.0.3(postcss@8.4.38): + postcss-font-variant@5.0.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 - postcss-discard-empty@6.0.3(postcss@8.4.38): + postcss-gap-properties@6.0.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 - postcss-discard-overridden@6.0.2(postcss@8.4.38): + postcss-image-set-function@7.0.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - postcss-discard-unused@6.0.5(postcss@8.4.38): + postcss-lab-function@7.0.7(postcss@8.5.1): dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/utilities': 2.0.0(postcss@8.5.1) + postcss: 8.5.1 - postcss-loader@7.3.4(postcss@8.4.38)(typescript@5.2.2)(webpack@5.91.0): + postcss-loader@7.3.4(postcss@8.5.1)(typescript@5.2.2)(webpack@5.97.1): dependencies: cosmiconfig: 8.3.6(typescript@5.2.2) - jiti: 1.21.0 - postcss: 8.4.38 - semver: 7.6.0 - webpack: 5.91.0 + jiti: 1.21.7 + postcss: 8.5.1 + semver: 7.6.3 + webpack: 5.97.1 transitivePeerDependencies: - typescript - postcss-merge-idents@6.0.3(postcss@8.4.38): + postcss-logical@8.0.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-merge-idents@6.0.3(postcss@8.5.1): dependencies: - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-merge-longhand@6.0.5(postcss@8.4.38): + postcss-merge-longhand@6.0.5(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - stylehacks: 6.1.1(postcss@8.4.38) + stylehacks: 6.1.1(postcss@8.5.1) - postcss-merge-rules@6.1.1(postcss@8.4.38): + postcss-merge-rules@6.1.1(postcss@8.5.1): dependencies: - browserslist: 4.23.0 + browserslist: 4.24.4 caniuse-api: 3.0.0 - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 - postcss-minify-font-values@6.1.0(postcss@8.4.38): + postcss-minify-font-values@6.1.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-minify-gradients@6.0.3(postcss@8.4.38): + postcss-minify-gradients@6.0.3(postcss@8.5.1): dependencies: colord: 2.9.3 - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-minify-params@6.1.0(postcss@8.4.38): + postcss-minify-params@6.1.0(postcss@8.5.1): dependencies: - browserslist: 4.23.0 - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 + browserslist: 4.24.4 + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-minify-selectors@6.0.4(postcss@8.4.38): + postcss-minify-selectors@6.0.4(postcss@8.5.1): dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@3.1.0(postcss@8.4.38): + postcss-modules-extract-imports@3.1.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 - postcss-modules-local-by-default@4.0.5(postcss@8.4.38): + postcss-modules-local-by-default@4.2.0(postcss@8.5.1): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + icss-utils: 5.1.0(postcss@8.5.1) + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.0(postcss@8.4.38): + postcss-modules-scope@3.2.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-modules-values@4.0.0(postcss@8.5.1): + dependencies: + icss-utils: 5.1.0(postcss@8.5.1) + postcss: 8.5.1 + + postcss-nesting@13.0.1(postcss@8.5.1): dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + '@csstools/selector-resolve-nested': 3.0.0(postcss-selector-parser@7.0.0) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.0.0) + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 - postcss-modules-values@4.0.0(postcss@8.4.38): + postcss-normalize-charset@6.0.2(postcss@8.5.1): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + postcss: 8.5.1 - postcss-normalize-charset@6.0.2(postcss@8.4.38): + postcss-normalize-display-values@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 + postcss-value-parser: 4.2.0 - postcss-normalize-display-values@6.0.2(postcss@8.4.38): + postcss-normalize-positions@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-positions@6.0.2(postcss@8.4.38): + postcss-normalize-repeat-style@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@6.0.2(postcss@8.4.38): + postcss-normalize-string@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-string@6.0.2(postcss@8.4.38): + postcss-normalize-timing-functions@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@6.0.2(postcss@8.4.38): + postcss-normalize-unicode@6.1.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + browserslist: 4.24.4 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@6.1.0(postcss@8.4.38): + postcss-normalize-url@6.0.2(postcss@8.5.1): dependencies: - browserslist: 4.23.0 - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-url@6.0.2(postcss@8.4.38): + postcss-normalize-whitespace@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@6.0.2(postcss@8.4.38): + postcss-opacity-percentage@3.0.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-ordered-values@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + cssnano-utils: 4.0.2(postcss@8.5.1) + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-ordered-values@6.0.2(postcss@8.4.38): + postcss-overflow-shorthand@6.0.0(postcss@8.5.1): dependencies: - cssnano-utils: 4.0.2(postcss@8.4.38) - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-reduce-idents@6.0.3(postcss@8.4.38): + postcss-page-break@3.0.4(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 + + postcss-place@10.0.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-value-parser: 4.2.0 + + postcss-preset-env@10.1.3(postcss@8.5.1): + dependencies: + '@csstools/postcss-cascade-layers': 5.0.1(postcss@8.5.1) + '@csstools/postcss-color-function': 4.0.7(postcss@8.5.1) + '@csstools/postcss-color-mix-function': 3.0.7(postcss@8.5.1) + '@csstools/postcss-content-alt-text': 2.0.4(postcss@8.5.1) + '@csstools/postcss-exponential-functions': 2.0.6(postcss@8.5.1) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.1) + '@csstools/postcss-gamut-mapping': 2.0.7(postcss@8.5.1) + '@csstools/postcss-gradients-interpolation-method': 5.0.7(postcss@8.5.1) + '@csstools/postcss-hwb-function': 4.0.7(postcss@8.5.1) + '@csstools/postcss-ic-unit': 4.0.0(postcss@8.5.1) + '@csstools/postcss-initial': 2.0.0(postcss@8.5.1) + '@csstools/postcss-is-pseudo-class': 5.0.1(postcss@8.5.1) + '@csstools/postcss-light-dark-function': 2.0.7(postcss@8.5.1) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.1) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.1) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.1) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.1) + '@csstools/postcss-logical-viewport-units': 3.0.3(postcss@8.5.1) + '@csstools/postcss-media-minmax': 2.0.6(postcss@8.5.1) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.4(postcss@8.5.1) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.1) + '@csstools/postcss-normalize-display-values': 4.0.0(postcss@8.5.1) + '@csstools/postcss-oklab-function': 4.0.7(postcss@8.5.1) + '@csstools/postcss-progressive-custom-properties': 4.0.0(postcss@8.5.1) + '@csstools/postcss-random-function': 1.0.2(postcss@8.5.1) + '@csstools/postcss-relative-color-syntax': 3.0.7(postcss@8.5.1) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.1) + '@csstools/postcss-sign-functions': 1.1.1(postcss@8.5.1) + '@csstools/postcss-stepped-value-functions': 4.0.6(postcss@8.5.1) + '@csstools/postcss-text-decoration-shorthand': 4.0.1(postcss@8.5.1) + '@csstools/postcss-trigonometric-functions': 4.0.6(postcss@8.5.1) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.1) + autoprefixer: 10.4.20(postcss@8.5.1) + browserslist: 4.24.4 + css-blank-pseudo: 7.0.1(postcss@8.5.1) + css-has-pseudo: 7.0.2(postcss@8.5.1) + css-prefers-color-scheme: 10.0.0(postcss@8.5.1) + cssdb: 8.2.3 + postcss: 8.5.1 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.1) + postcss-clamp: 4.1.0(postcss@8.5.1) + postcss-color-functional-notation: 7.0.7(postcss@8.5.1) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.1) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.1) + postcss-custom-media: 11.0.5(postcss@8.5.1) + postcss-custom-properties: 14.0.4(postcss@8.5.1) + postcss-custom-selectors: 8.0.4(postcss@8.5.1) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.1) + postcss-double-position-gradients: 6.0.0(postcss@8.5.1) + postcss-focus-visible: 10.0.1(postcss@8.5.1) + postcss-focus-within: 9.0.1(postcss@8.5.1) + postcss-font-variant: 5.0.0(postcss@8.5.1) + postcss-gap-properties: 6.0.0(postcss@8.5.1) + postcss-image-set-function: 7.0.0(postcss@8.5.1) + postcss-lab-function: 7.0.7(postcss@8.5.1) + postcss-logical: 8.0.0(postcss@8.5.1) + postcss-nesting: 13.0.1(postcss@8.5.1) + postcss-opacity-percentage: 3.0.0(postcss@8.5.1) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.1) + postcss-page-break: 3.0.4(postcss@8.5.1) + postcss-place: 10.0.0(postcss@8.5.1) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.1) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.1) + postcss-selector-not: 8.0.1(postcss@8.5.1) + + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-reduce-idents@6.0.3(postcss@8.5.1): + dependencies: + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-reduce-initial@6.1.0(postcss@8.4.38): + postcss-reduce-initial@6.1.0(postcss@8.5.1): dependencies: - browserslist: 4.23.0 + browserslist: 4.24.4 caniuse-api: 3.0.0 - postcss: 8.4.38 + postcss: 8.5.1 - postcss-reduce-transforms@6.0.2(postcss@8.4.38): + postcss-reduce-transforms@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - postcss-selector-parser@6.0.16: + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + + postcss-selector-not@8.0.1(postcss@8.5.1): + dependencies: + postcss: 8.5.1 + postcss-selector-parser: 7.0.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.0.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sort-media-queries@5.2.0(postcss@8.4.38): + postcss-sort-media-queries@5.2.0(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 sort-css-media-queries: 2.2.0 - postcss-svgo@6.0.3(postcss@8.4.38): + postcss-svgo@6.0.3(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 postcss-value-parser: 4.2.0 - svgo: 3.2.0 + svgo: 3.3.2 - postcss-unique-selectors@6.0.4(postcss@8.4.38): + postcss-unique-selectors@6.0.4(postcss@8.5.1): dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} - postcss-zindex@6.0.2(postcss@8.4.38): + postcss-zindex@6.0.2(postcss@8.5.1): dependencies: - postcss: 8.4.38 + postcss: 8.5.1 - postcss@8.4.38: + postcss@8.5.1: dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.2.0 + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -13615,6 +15824,8 @@ snapshots: prettier@2.8.3: {} + prettier@3.4.2: {} + pretty-error@4.0.0: dependencies: lodash: 4.17.21 @@ -13622,9 +15833,14 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.3.1(react@18.3.1): + pretty-tree@1.0.0: + dependencies: + archy: 0.0.2 + chalk: 1.0.0 + + prism-react-renderer@2.4.1(react@18.3.1): dependencies: - '@types/prismjs': 1.26.4 + '@types/prismjs': 1.26.5 clsx: 2.1.1 react: 18.3.1 @@ -13649,7 +15865,7 @@ snapshots: proto-list@1.2.4: {} - protobufjs@7.2.6: + protobufjs@7.4.0: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -13661,25 +15877,23 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.12.10 - long: 5.2.3 + '@types/node': 20.17.14 + long: 5.2.4 proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - punycode@1.4.1: {} - punycode@2.3.1: {} pupa@3.1.0: dependencies: escape-goat: 4.0.0 - qs@6.11.0: + qs@6.13.0: dependencies: - side-channel: 1.0.6 + side-channel: 1.1.0 queue-microtask@1.2.3: {} @@ -13713,33 +15927,33 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.2.2)(webpack@5.91.0): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.2.2)(webpack@5.97.1): dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.26.2 address: 1.2.2 - browserslist: 4.23.0 + browserslist: 4.24.4 chalk: 4.1.2 - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 detect-port-alt: 1.1.6 escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.0)(typescript@5.2.2)(webpack@5.91.0) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.2.2)(webpack@5.97.1) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 immer: 9.0.21 is-root: 2.1.0 - loader-utils: 3.2.1 + loader-utils: 3.3.1 open: 8.4.2 pkg-up: 3.1.0 prompts: 2.4.2 react-error-overlay: 6.0.11 recursive-readdir: 2.2.3 - shell-quote: 1.8.1 + shell-quote: 1.8.2 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.91.0 + webpack: 5.97.1 optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: @@ -13757,34 +15971,17 @@ snapshots: react-fast-compare@3.2.2: {} - react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.24.5 - invariant: 2.2.4 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-fast-compare: 3.2.2 - shallowequal: 1.1.0 - - react-helmet-async@2.0.5(react@18.3.1): - dependencies: - invariant: 2.2.4 - react: 18.3.1 - react-fast-compare: 3.2.2 - shallowequal: 1.1.0 - react-is@16.13.1: {} - react-json-view-lite@1.4.0(react@18.3.1): + react-json-view-lite@1.5.0(react@18.3.1): dependencies: react: 18.3.1 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.91.0): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.97.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - webpack: 5.91.0 + webpack: 5.97.1 react-native-fetch-api@3.0.0: dependencies: @@ -13792,13 +15989,13 @@ snapshots: react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 react: 18.3.1 react-router: 5.3.4(react@18.3.1) react-router-dom@5.3.4(react@18.3.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -13809,11 +16006,11 @@ snapshots: react-router@5.3.4(react@18.3.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - path-to-regexp: 1.8.0 + path-to-regexp: 1.9.0 prop-types: 15.8.1 react: 18.3.1 react-is: 16.13.1 @@ -13854,17 +16051,54 @@ snapshots: rechoir@0.6.2: dependencies: - resolve: 1.22.8 + resolve: 1.22.10 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.6 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.0(acorn@8.14.0): + dependencies: + acorn-jsx: 5.3.2(acorn@8.14.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - acorn + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.6 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.6 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 recursive-readdir@2.2.3: dependencies: minimatch: 3.1.2 - redeyed@2.1.1: + reflect.getprototypeof@1.0.10: dependencies: - esprima: 4.0.1 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.1.1: + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -13874,82 +16108,94 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@5.3.2: + regexpu-core@6.2.0: dependencies: - '@babel/regjsgen': 0.8.0 regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.12.0 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 + unicode-match-property-value-ecmascript: 2.2.0 - registry-auth-token@5.0.2: + registry-auth-token@5.0.3: dependencies: - '@pnpm/npm-conf': 2.2.2 + '@pnpm/npm-conf': 2.3.1 registry-url@6.0.1: dependencies: rc: 1.2.8 - regjsparser@0.9.1: + regjsgen@0.8.0: {} + + regjsparser@0.12.0: dependencies: - jsesc: 0.5.0 + jsesc: 3.0.2 rehype-raw@7.0.0: dependencies: '@types/hast': 3.0.4 - hast-util-raw: 9.0.3 - vfile: 6.0.1 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.6 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.1 + transitivePeerDependencies: + - supports-color relateurl@0.2.7: {} remark-directive@3.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-directive: 3.0.0 - micromark-extension-directive: 3.0.0 - unified: 11.0.4 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 transitivePeerDependencies: - supports-color remark-emoji@4.0.1: dependencies: - '@types/mdast': 4.0.3 - emoticon: 4.0.1 - mdast-util-find-and-replace: 3.0.1 - node-emoji: 2.1.3 - unified: 11.0.4 + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.2 + node-emoji: 2.2.0 + unified: 11.0.5 remark-frontmatter@5.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-frontmatter: 2.0.1 micromark-extension-frontmatter: 2.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color remark-gfm@4.0.0: dependencies: - '@types/mdast': 4.0.3 + '@types/mdast': 4.0.4 mdast-util-gfm: 3.0.0 micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color - remark-mdx@3.0.1: + remark-mdx@3.1.0: dependencies: mdast-util-mdx: 3.0.0 micromark-extension-mdxjs: 3.0.0 @@ -13958,26 +16204,26 @@ snapshots: remark-parse@11.0.0: dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.0 - micromark-util-types: 2.0.0 - unified: 11.0.4 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.1 + unified: 11.0.5 transitivePeerDependencies: - supports-color - remark-rehype@11.1.0: + remark-rehype@11.1.1: dependencies: '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - mdast-util-to-hast: 13.1.0 - unified: 11.0.4 - vfile: 6.0.1 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 remark-stringify@11.0.0: dependencies: - '@types/mdast': 4.0.3 - mdast-util-to-markdown: 2.1.0 - unified: 11.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 renderkid@3.0.0: dependencies: @@ -13987,6 +16233,8 @@ snapshots: lodash: 4.17.21 strip-ansi: 6.0.1 + repeat-string@1.6.1: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -14010,9 +16258,9 @@ snapshots: resolve-pathname@3.0.0: {} - resolve@1.22.8: + resolve@1.22.10: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -14029,53 +16277,65 @@ snapshots: reusify@1.0.4: {} - rfdc@1.3.1: {} + rfdc@1.4.1: {} rimraf@3.0.2: dependencies: glob: 7.2.3 - rtl-detect@1.1.2: {} - - rtlcss@4.1.1: + rtlcss@4.3.0: dependencies: - escalade: 3.1.2 - picocolors: 1.0.0 - postcss: 8.4.38 + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.5.1 strip-json-comments: 3.1.1 + run-applescript@5.0.0: + dependencies: + execa: 5.1.1 + + run-async@3.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 rxjs@7.8.1: dependencies: - tslib: 2.6.2 + tslib: 2.8.1 + + s-ago@2.2.0: {} sade@1.8.1: dependencies: mri: 1.2.0 - safe-array-concat@1.1.2: + safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} - safe-regex-test@1.0.3: + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - is-regex: 1.1.4 + is-regex: 1.2.1 safer-buffer@2.1.2: {} - sax@1.3.0: {} + sax@1.4.1: {} scheduler@0.23.2: dependencies: @@ -14093,14 +16353,14 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.2.0: + schema-utils@4.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.13.0 - ajv-formats: 2.1.1(ajv@8.13.0) - ajv-keywords: 5.1.0(ajv@8.13.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) - search-insights@2.13.0: {} + search-insights@2.17.3: {} section-matter@1.0.0: dependencies: @@ -14118,17 +16378,15 @@ snapshots: semver-diff@4.0.0: dependencies: - semver: 7.6.0 + semver: 7.6.3 semver@5.7.2: {} semver@6.3.1: {} - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 + semver@7.6.3: {} - send@0.18.0: + send@0.19.0: dependencies: debug: 2.6.9 depd: 2.0.0 @@ -14146,23 +16404,18 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@6.0.0: - dependencies: - randombytes: 2.1.0 - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 - serve-handler@6.1.5: + serve-handler@6.1.6: dependencies: bytes: 3.0.0 content-disposition: 0.5.2 - fast-url-parser: 1.1.3 mime-types: 2.1.18 minimatch: 3.1.2 path-is-inside: 1.0.2 - path-to-regexp: 2.2.1 + path-to-regexp: 3.3.0 range-parser: 1.2.0 serve-index@1.9.1: @@ -14177,12 +16430,12 @@ snapshots: transitivePeerDependencies: - supports-color - serve-static@1.15.0: + serve-static@1.16.2: dependencies: - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.18.0 + send: 0.19.0 transitivePeerDependencies: - supports-color @@ -14191,8 +16444,8 @@ snapshots: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 + get-intrinsic: 1.2.7 + gopd: 1.2.0 has-property-descriptors: 1.0.2 set-function-name@2.0.2: @@ -14202,6 +16455,12 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + setprototypeof@1.1.0: {} setprototypeof@1.2.0: {} @@ -14224,7 +16483,7 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.1: {} + shell-quote@1.8.2: {} shelljs@0.8.5: dependencies: @@ -14235,16 +16494,37 @@ snapshots: shiki@0.14.7: dependencies: ansi-sequence-parser: 1.1.1 - jsonc-parser: 3.2.1 + jsonc-parser: 3.3.1 vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 - side-channel@1.0.6: + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + + side-channel-weakmap@1.0.2: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 signal-exit@3.0.7: {} @@ -14254,25 +16534,25 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 '@sinonjs/fake-timers': 10.3.0 - '@sinonjs/samsam': 8.0.0 + '@sinonjs/samsam': 8.0.2 diff: 5.2.0 nise: 5.1.9 supports-color: 7.2.0 sirv@2.0.4: dependencies: - '@polka/url': 1.0.0-next.25 + '@polka/url': 1.0.0-next.28 mrmime: 2.0.0 totalist: 3.0.1 sisteransi@1.0.5: {} - sitemap@7.1.1: + sitemap@7.1.2: dependencies: '@types/node': 17.0.45 '@types/sax': 1.2.7 arg: 5.0.2 - sax: 1.3.0 + sax: 1.4.1 skin-tone@2.0.0: dependencies: @@ -14292,7 +16572,7 @@ snapshots: snake-case@3.0.4: dependencies: dot-case: 3.0.4 - tslib: 2.6.2 + tslib: 2.8.1 sockjs@0.3.24: dependencies: @@ -14302,7 +16582,7 @@ snapshots: sort-css-media-queries@2.2.0: {} - source-map-js@1.2.0: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: dependencies: @@ -14320,25 +16600,25 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.17 + spdx-license-ids: 3.0.21 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.17 + spdx-license-ids: 3.0.21 spdx-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.17 + spdx-license-ids: 3.0.21 - spdx-license-ids@3.0.17: {} + spdx-license-ids@3.0.21: {} spdy-transport@3.0.0: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -14349,7 +16629,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -14365,7 +16645,7 @@ snapshots: statuses@2.0.1: {} - std-env@3.7.0: {} + std-env@3.8.0: {} stdin-discarder@0.1.0: dependencies: @@ -14397,34 +16677,44 @@ snapshots: string-width@6.1.0: dependencies: eastasianwidth: 0.2.0 - emoji-regex: 10.3.0 + emoji-regex: 10.4.0 + strip-ansi: 7.1.0 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 string.prototype.padend@3.1.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 - string.prototype.trim@1.2.9: + string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 - string.prototype.trimend@1.0.8: + string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.1.1: dependencies: @@ -14445,13 +16735,17 @@ snapshots: is-obj: 1.0.1 is-regexp: 1.0.0 + strip-ansi@2.0.1: + dependencies: + ansi-regex: 1.1.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom-string@1.0.0: {} @@ -14467,19 +16761,17 @@ snapshots: stubborn-fs@1.2.5: {} - style-to-object@0.4.4: + style-to-object@1.0.8: dependencies: - inline-style-parser: 0.1.1 + inline-style-parser: 0.2.4 - style-to-object@1.0.6: + stylehacks@6.1.1(postcss@8.5.1): dependencies: - inline-style-parser: 0.2.3 + browserslist: 4.24.4 + postcss: 8.5.1 + postcss-selector-parser: 6.1.2 - stylehacks@6.1.1(postcss@8.4.38): - dependencies: - browserslist: 4.23.0 - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + supports-color@1.3.1: {} supports-color@5.5.0: dependencies: @@ -14493,7 +16785,7 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-hyperlinks@3.0.0: + supports-hyperlinks@3.1.0: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 @@ -14502,7 +16794,7 @@ snapshots: svg-parser@2.0.4: {} - svgo@3.2.0: + svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 @@ -14510,11 +16802,11 @@ snapshots: css-tree: 2.3.1 css-what: 6.1.0 csso: 5.0.5 - picocolors: 1.0.0 + picocolors: 1.1.1 sync-multihash-sha2@1.0.0: dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.7.1 tapable@1.1.3: {} @@ -14529,19 +16821,19 @@ snapshots: type-fest: 2.19.0 unique-string: 3.0.0 - terser-webpack-plugin@5.3.10(webpack@5.91.0): + terser-webpack-plugin@5.3.11(webpack@5.97.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 - schema-utils: 3.3.0 + schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.31.0 - webpack: 5.91.0 + terser: 5.37.0 + webpack: 5.97.1 - terser@5.31.0: + terser@5.37.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.11.3 + acorn: 8.14.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -14555,17 +16847,29 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 10.4.5 - minimatch: 9.0.4 + minimatch: 9.0.5 text-table@0.2.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + thunky@1.1.0: {} tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} - to-fast-properties@2.0.0: {} + titleize@3.0.0: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 to-regex-range@5.0.1: dependencies: @@ -14585,13 +16889,13 @@ snapshots: dependencies: matchit: 1.1.0 - ts-api-utils@1.3.0(typescript@5.3.3): + ts-api-utils@1.4.3(typescript@5.3.3): dependencies: typescript: 5.3.3 ts-expose-internals-conditionally@1.0.0-empty.0: {} - tslib@2.6.2: {} + tslib@2.8.1: {} type-check@0.4.0: dependencies: @@ -14599,52 +16903,57 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.20.2: {} + type-fest@0.21.3: {} + type-fest@1.4.0: {} type-fest@2.19.0: {} type-fest@3.13.1: {} - type-fest@4.18.2: {} + type-fest@4.33.0: {} type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - typed-array-buffer@1.0.2: + typed-array-buffer@1.0.3: dependencies: - call-bind: 1.0.7 + call-bound: 1.0.3 es-errors: 1.3.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: + typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.2: + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 - typed-array-length@1.0.6: + typed-array-length@1.0.7: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 - is-typed-array: 1.1.13 + gopd: 1.2.0 + is-typed-array: 1.1.15 possible-typed-array-names: 1.0.0 + reflect.getprototypeof: 1.0.10 typedarray-to-buffer@3.1.5: dependencies: @@ -14655,7 +16964,7 @@ snapshots: handlebars: 4.7.8 typedoc: 0.25.13(typescript@5.2.2) - typedoc-plugin-missing-exports@2.2.0(typedoc@0.25.13(typescript@5.2.2)): + typedoc-plugin-missing-exports@2.3.0(typedoc@0.25.13(typescript@5.2.2)): dependencies: typedoc: 0.25.13(typescript@5.2.2) @@ -14663,7 +16972,7 @@ snapshots: dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.4 + minimatch: 9.0.5 shiki: 0.14.7 typescript: 5.2.2 @@ -14671,54 +16980,54 @@ snapshots: typescript@5.3.3: {} - uglify-js@3.17.4: + uglify-js@3.19.3: optional: true uint8arraylist@2.4.8: dependencies: - uint8arrays: 5.0.3 + uint8arrays: 5.1.0 uint8arrays@4.0.10: dependencies: multiformats: 12.1.3 - uint8arrays@5.0.3: + uint8arrays@5.1.0: dependencies: - multiformats: 13.1.0 + multiformats: 13.3.1 - unbox-primitive@1.0.2: + unbox-primitive@1.1.0: dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 + call-bound: 1.0.3 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 - undici-types@5.26.5: {} + undici-types@6.19.8: {} - unicode-canonical-property-names-ecmascript@2.0.0: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-emoji-modifier-base@1.0.0: {} unicode-match-property-ecmascript@2.0.0: dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-canonical-property-names-ecmascript: 2.0.1 unicode-property-aliases-ecmascript: 2.1.0 - unicode-match-property-value-ecmascript@2.1.0: {} + unicode-match-property-value-ecmascript@2.2.0: {} unicode-property-aliases-ecmascript@2.1.0: {} unicorn-magic@0.1.0: {} - unified@11.0.4: + unified@11.0.5: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 is-plain-obj: 4.1.0 trough: 2.2.0 - vfile: 6.0.1 + vfile: 6.0.3 unique-string@3.0.0: dependencies: @@ -14726,33 +17035,28 @@ snapshots: unist-util-is@6.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-position-from-estree@2.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-position@5.0.0: dependencies: - '@types/unist': 3.0.2 - - unist-util-remove-position@5.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-visit: 5.0.0 + '@types/unist': 3.0.3 unist-util-stringify-position@4.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-visit-parents@6.0.1: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit@5.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 @@ -14760,16 +17064,18 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.0.15(browserslist@4.23.0): + untildify@4.0.0: {} + + update-browserslist-db@1.1.2(browserslist@4.24.4): dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.0 + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 update-notifier@6.0.2: dependencies: boxen: 7.1.1 - chalk: 5.3.0 + chalk: 5.4.1 configstore: 6.0.0 has-yarn: 3.0.0 import-lazy: 4.0.0 @@ -14779,32 +17085,45 @@ snapshots: is-yarn-global: 0.4.1 latest-version: 7.0.0 pupa: 3.1.0 - semver: 7.6.0 + semver: 7.6.3 semver-diff: 4.0.0 xdg-basedir: 5.1.0 + update-notifier@7.3.1: + dependencies: + boxen: 8.0.1 + chalk: 5.4.1 + configstore: 7.0.0 + is-in-ci: 1.0.0 + is-installed-globally: 1.0.0 + is-npm: 6.0.0 + latest-version: 9.0.0 + pupa: 3.1.0 + semver: 7.6.3 + xdg-basedir: 5.1.0 + uri-js@4.4.1: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.91.0))(webpack@5.91.0): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.97.1))(webpack@5.97.1): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.91.0 + webpack: 5.97.1 optionalDependencies: - file-loader: 6.2.0(webpack@5.91.0) + file-loader: 6.2.0(webpack@5.97.1) util-deprecate@1.0.2: {} util@0.12.5: dependencies: inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.13 - which-typed-array: 1.1.15 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.18 utila@0.4.0: {} @@ -14821,7 +17140,7 @@ snapshots: kleur: 4.1.5 sade: 1.8.1 - v8-to-istanbul@9.2.0: + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 @@ -14840,20 +17159,19 @@ snapshots: vary@1.1.2: {} - vfile-location@5.0.2: + vfile-location@5.0.3: dependencies: - '@types/unist': 3.0.2 - vfile: 6.0.1 + '@types/unist': 3.0.3 + vfile: 6.0.3 vfile-message@4.0.2: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 - vfile@6.0.1: + vfile@6.0.3: dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 + '@types/unist': 3.0.3 vfile-message: 4.0.2 vscode-oniguruma@1.7.0: {} @@ -14865,7 +17183,7 @@ snapshots: exec-sh: 0.2.2 minimist: 1.2.8 - watchpack@2.4.1: + watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -14889,31 +17207,31 @@ snapshots: webpack-bundle-analyzer@4.10.2: dependencies: '@discoveryjs/json-ext': 0.5.7 - acorn: 8.11.3 - acorn-walk: 8.3.2 + acorn: 8.14.0 + acorn-walk: 8.3.4 commander: 7.2.0 debounce: 1.2.1 escape-string-regexp: 4.0.0 gzip-size: 6.0.0 html-escaper: 2.0.2 opener: 1.5.2 - picocolors: 1.0.0 + picocolors: 1.1.1 sirv: 2.0.4 - ws: 7.5.9 + ws: 7.5.10 transitivePeerDependencies: - bufferutil - utf-8-validate - webpack-dev-middleware@5.3.4(webpack@5.91.0): + webpack-dev-middleware@5.3.4(webpack@5.97.1): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 - schema-utils: 4.2.0 - webpack: 5.91.0 + schema-utils: 4.3.0 + webpack: 5.97.1 - webpack-dev-server@4.15.2(webpack@5.91.0): + webpack-dev-server@4.15.2(webpack@5.97.1): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -14921,32 +17239,32 @@ snapshots: '@types/serve-index': 1.9.4 '@types/serve-static': 1.15.7 '@types/sockjs': 0.3.36 - '@types/ws': 8.5.10 + '@types/ws': 8.5.13 ansi-html-community: 0.0.8 - bonjour-service: 1.2.1 + bonjour-service: 1.3.0 chokidar: 3.6.0 colorette: 2.0.20 - compression: 1.7.4 + compression: 1.7.5 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.19.2 + express: 4.21.2 graceful-fs: 4.2.11 html-entities: 2.5.2 - http-proxy-middleware: 2.0.6(@types/express@4.17.21) + http-proxy-middleware: 2.0.7(@types/express@4.17.21) ipaddr.js: 2.2.0 - launch-editor: 2.6.1 + launch-editor: 2.9.1 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 - schema-utils: 4.2.0 + schema-utils: 4.3.0 selfsigned: 2.4.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.91.0) - ws: 8.17.0 + webpack-dev-middleware: 5.3.4(webpack@5.97.1) + ws: 8.18.0 optionalDependencies: - webpack: 5.91.0 + webpack: 5.97.1 transitivePeerDependencies: - bufferutil - debug @@ -14959,21 +17277,26 @@ snapshots: flat: 5.0.2 wildcard: 2.0.1 + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + webpack-sources@3.2.3: {} - webpack@5.91.0: + webpack@5.97.1: dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) - browserslist: 4.23.0 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.16.0 - es-module-lexer: 1.5.2 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.0 + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.0 + es-module-lexer: 1.6.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -14984,25 +17307,29 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.91.0) - watchpack: 2.4.1 + terser-webpack-plugin: 5.3.11(webpack@5.97.1) + watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpackbar@5.0.2(webpack@5.91.0): + webpackbar@6.0.1(webpack@5.97.1): dependencies: + ansi-escapes: 4.3.2 chalk: 4.1.2 - consola: 2.15.3 + consola: 3.4.0 + figures: 3.2.0 + markdown-table: 2.0.0 pretty-time: 1.1.0 - std-env: 3.7.0 - webpack: 5.91.0 + std-env: 3.8.0 + webpack: 5.97.1 + wrap-ansi: 7.0.0 websocket-driver@0.7.4: dependencies: - http-parser-js: 0.5.8 + http-parser-js: 0.5.9 safe-buffer: 5.2.1 websocket-extensions: 0.1.4 @@ -15013,22 +17340,46 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - when-exit@2.1.2: {} + when-exit@2.1.4: {} + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.1 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.3 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.0 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.0 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 - which-boxed-primitive@1.0.2: + which-collection@1.0.2: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 - which-typed-array@1.1.15: + which-typed-array@1.1.18: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.2.0 has-tostringtag: 1.0.2 which@1.3.1: @@ -15043,13 +17394,23 @@ snapshots: dependencies: string-width: 5.1.2 + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + wildcard@2.0.1: {} word-wrap@1.2.5: {} wordwrap@1.0.0: {} - workerpool@6.2.1: {} + workerpool@6.5.1: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 wrap-ansi@7.0.0: dependencies: @@ -15063,6 +17424,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@3.0.3: @@ -15072,28 +17439,24 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - ws@7.5.9: {} + ws@7.5.10: {} - ws@8.17.0: {} + ws@8.18.0: {} xdg-basedir@5.1.0: {} xml-js@1.6.11: dependencies: - sax: 1.3.0 + sax: 1.4.1 y18n@5.0.8: {} yallist@3.1.1: {} - yallist@4.0.0: {} - yaml@1.10.2: {} yaml@2.3.1: {} - yargs-parser@20.2.4: {} - yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} @@ -15108,7 +17471,7 @@ snapshots: yargs@16.2.0: dependencies: cliui: 7.0.4 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -15118,7 +17481,7 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -15127,6 +17490,6 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.0.0: {} + yocto-queue@1.1.1: {} zwitch@2.0.4: {} diff --git a/scripts/mkdelegate.js b/scripts/mkdelegate.js new file mode 100644 index 000000000..fb1f2ba18 --- /dev/null +++ b/scripts/mkdelegate.js @@ -0,0 +1,85 @@ +/** + * Utility to create delegations for actors in the network. + * + * Usage: + * node mkdelegate.js + */ +import { delegate } from '@ucanto/core' +import * as ed25519 from '@ucanto/principal/ed25519' +import * as Link from 'multiformats/link' +import { identity } from 'multiformats/hashes/identity' +import { base64 } from 'multiformats/bases/base64' +import * as DID from '@ipld/dag-ucan/did' + +const indexingServiceDID = 'did:web:staging.indexer.storacha.network' +const uploadServiceDID = 'did:web:staging.upload.storacha.network' +const storageProviderDID = 'did:key:...' + +if (!process.argv[2]) { + console.error('missing private key arg') + process.exit(1) +} + +// @ts-expect-error +const delegateIndexingServiceToUploadService = async () => { + const issuer = ed25519.parse(process.argv[2]).withDID(indexingServiceDID) + const audience = DID.parse(uploadServiceDID) + + const delegation = await delegate({ + issuer, + audience, + capabilities: [ + { can: 'assert/equals', with: issuer.did(), nb: {} }, + { can: 'assert/index', with: issuer.did(), nb: {} }, + ], + expiration: Infinity, + }) + + console.log(await formatDelegation(delegation)) +} +// delegateIndexingServiceToUploadService() + +// @ts-expect-error +const delegateStorageProviderToUploadService = async () => { + const issuer = ed25519.parse(process.argv[2]) + const audience = DID.parse(uploadServiceDID) + + const delegation = await delegate({ + issuer, + audience, + capabilities: [ + { can: 'blob/allocate', with: issuer.did(), nb: {} }, + { can: 'blob/accept', with: issuer.did(), nb: {} }, + ], + expiration: Infinity, + }) + + console.log(await formatDelegation(delegation)) +} +// delegateStorageProviderToUploadService() + +// @ts-expect-error +const delegateIndexingServiceToStorageProvider = async () => { + const issuer = ed25519.parse(process.argv[2]).withDID(indexingServiceDID) + const audience = DID.parse(storageProviderDID) + + const delegation = await delegate({ + issuer, + audience, + capabilities: [{ can: 'claim/cache', with: issuer.did(), nb: {} }], + expiration: Infinity, + }) + + console.log(await formatDelegation(delegation)) +} +// delegateIndexingServiceToStorageProvider() + +/** @param {import('@ucanto/interface').Delegation} delegation */ +const formatDelegation = async (delegation) => { + const { ok: archive, error } = await delegation.archive() + if (error) throw error + + const digest = identity.digest(archive) + const link = Link.create(0x0202, digest) + return link.toString(base64) +} diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 000000000..72748a655 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,14 @@ +{ + "name": "@storacha/upload-service-scripts", + "version": "0.0.0", + "main": "index.js", + "type": "module", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "@ipld/dag-ucan": "^3.4.0", + "@ucanto/core": "^10.0.1", + "@ucanto/interface": "^10.0.1", + "@ucanto/principal": "^9.0.1", + "multiformats": "^13.3.1" + } +} diff --git a/tsconfig.json b/tsconfig.json index fb919f145..3af3d13d1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -46,7 +46,7 @@ "excludeExternals": true, "darkHighlightTheme": "github-dark", "navigationLinks": { - "Github": "https://github.com/storacha/w3up" + "Github": "https://github.com/storacha/upload-service" }, "customCss": "./packages/w3up-typedoc-config/static/docs.css" }