From 752b3bf14cd3463b07cbeee541b67c3ac2ac41f5 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 16 Aug 2023 15:04:02 -0500
Subject: [PATCH 001/137] Initial commit
---
services/content-watcher/LICENSE | 201 +++++++++++++++++++++++++++++
services/content-watcher/README.md | 2 +
2 files changed, 203 insertions(+)
create mode 100644 services/content-watcher/LICENSE
create mode 100644 services/content-watcher/README.md
diff --git a/services/content-watcher/LICENSE b/services/content-watcher/LICENSE
new file mode 100644
index 00000000..261eeb9e
--- /dev/null
+++ b/services/content-watcher/LICENSE
@@ -0,0 +1,201 @@
+ 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
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/services/content-watcher/README.md b/services/content-watcher/README.md
new file mode 100644
index 00000000..728b40be
--- /dev/null
+++ b/services/content-watcher/README.md
@@ -0,0 +1,2 @@
+# content-publishing-service
+A microservice to publish DSNP content to frequency
From 8d46c85a59e81209e524dddb265d78d5e3eaf7ee Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Mon, 21 Aug 2023 13:15:24 -0500
Subject: [PATCH 002/137] Basic Scaffolding (#1)
* base nestjs for content publishing
* fix build
* feedback
---
services/content-watcher/.eslintrc.json | 64 +
.../.github/workflows/build.yml | 59 +
.../common/is-full-release/action.yml | 22 +
.../.github/workflows/release.yml | 99 +
services/content-watcher/.gitignore | 5 +
services/content-watcher/.prettierrc | 10 +
services/content-watcher/.tool-versions | 1 +
services/content-watcher/Dockerfile | 32 +
services/content-watcher/INSTALLING.md | 72 +
services/content-watcher/README.md | 5 +-
services/content-watcher/dev.Dockerfile | 6 +
.../content-watcher/docker-compose.dev.yaml | 38 +
services/content-watcher/env.template | 18 +
services/content-watcher/jest.config.js | 7 +
services/content-watcher/package-lock.json | 9649 +++++++++++++++++
services/content-watcher/package.json | 86 +
.../src/blockchain/blockchain-constants.ts | 29 +
.../src/blockchain/blockchain.module.ts | 15 +
.../src/blockchain/blockchain.service.ts | 138 +
.../src/blockchain/create-keys.ts | 15 +
.../src/blockchain/event-error.ts | 34 +
.../src/blockchain/extrinsic.ts | 116 +
.../src/config/config.module.ts | 12 +
.../src/config/config.service.spec.ts | 251 +
.../src/config/config.service.ts | 91 +
.../content-watcher/src/config/env.config.ts | 64 +
.../content-publishing-service.controller.ts | 18 +
.../src/content-publishing-service.module.ts | 51 +
.../src/development.controller.ts | 21 +
.../interfaces/capacity-limit.interface.ts | 4 +
services/content-watcher/src/main.ts | 38 +
services/content-watcher/tsconfig.json | 38 +
32 files changed, 11106 insertions(+), 2 deletions(-)
create mode 100644 services/content-watcher/.eslintrc.json
create mode 100644 services/content-watcher/.github/workflows/build.yml
create mode 100644 services/content-watcher/.github/workflows/common/is-full-release/action.yml
create mode 100644 services/content-watcher/.github/workflows/release.yml
create mode 100644 services/content-watcher/.gitignore
create mode 100644 services/content-watcher/.prettierrc
create mode 100644 services/content-watcher/.tool-versions
create mode 100644 services/content-watcher/Dockerfile
create mode 100644 services/content-watcher/INSTALLING.md
create mode 100644 services/content-watcher/dev.Dockerfile
create mode 100644 services/content-watcher/docker-compose.dev.yaml
create mode 100644 services/content-watcher/env.template
create mode 100644 services/content-watcher/jest.config.js
create mode 100644 services/content-watcher/package-lock.json
create mode 100644 services/content-watcher/package.json
create mode 100644 services/content-watcher/src/blockchain/blockchain-constants.ts
create mode 100644 services/content-watcher/src/blockchain/blockchain.module.ts
create mode 100644 services/content-watcher/src/blockchain/blockchain.service.ts
create mode 100644 services/content-watcher/src/blockchain/create-keys.ts
create mode 100644 services/content-watcher/src/blockchain/event-error.ts
create mode 100644 services/content-watcher/src/blockchain/extrinsic.ts
create mode 100644 services/content-watcher/src/config/config.module.ts
create mode 100644 services/content-watcher/src/config/config.service.spec.ts
create mode 100644 services/content-watcher/src/config/config.service.ts
create mode 100644 services/content-watcher/src/config/env.config.ts
create mode 100644 services/content-watcher/src/content-publishing-service.controller.ts
create mode 100644 services/content-watcher/src/content-publishing-service.module.ts
create mode 100644 services/content-watcher/src/development.controller.ts
create mode 100644 services/content-watcher/src/interfaces/capacity-limit.interface.ts
create mode 100644 services/content-watcher/src/main.ts
create mode 100644 services/content-watcher/tsconfig.json
diff --git a/services/content-watcher/.eslintrc.json b/services/content-watcher/.eslintrc.json
new file mode 100644
index 00000000..98fe9ce2
--- /dev/null
+++ b/services/content-watcher/.eslintrc.json
@@ -0,0 +1,64 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true
+ },
+ "extends": [
+ "airbnb-base",
+ "prettier"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "project": "./tsconfig.json",
+ "sourceType": "module"
+ },
+ "settings": {
+ "import/extensions": [
+ "error",
+ "ignorePackages",
+ {
+ "js": "never",
+ "jsx": "never",
+ "ts": "never",
+ "tsx": "never"
+ }
+ ],
+ "import/parsers": {
+ "@typescript-eslint/parser": [".ts", ".tsx"]
+ },
+ "import/resolver": {
+ "typescript": {
+ "directory": "./tsconfig.json"
+ },
+ "node": {
+ "extensions": [".js", ".jsx", ".ts", ".d.ts", ".tsx"]
+ }
+ },
+ "react": {
+ "version": "999.99.99"
+ }
+ },
+ "rules": {
+ "no-console": "off",
+ "import/extensions": [
+ "error",
+ "ignorePackages",
+ {
+ "js": "never",
+ "jsx": "never",
+ "ts": "never",
+ "tsx": "never"
+ }
+ ],
+ "import/no-unresolved": [2, { "commonjs": true, "amd": true }],
+ "import/named": 2,
+ "import/namespace": 2,
+ "import/default": 2,
+ "import/export": 2,
+ "import/prefer-default-export": "off",
+ "indent": "off",
+ "no-unused-vars": "off",
+ "prettier/prettier": 2
+ },
+ "plugins": ["import", "prettier"]
+}
diff --git a/services/content-watcher/.github/workflows/build.yml b/services/content-watcher/.github/workflows/build.yml
new file mode 100644
index 00000000..2a456a84
--- /dev/null
+++ b/services/content-watcher/.github/workflows/build.yml
@@ -0,0 +1,59 @@
+name: Build And Test ContentPublishing Service
+concurrency:
+ group: ${{github.workflow}}-${{github.ref}}
+ cancel-in-progress: true
+on:
+ pull_request:
+ branches:
+ - main
+ push:
+ branches:
+ - main
+
+jobs:
+ build_Nest_js:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+ registry-url: 'https://registry.npmjs.org'
+ cache-dependency-path: package-lock.json
+ - name: Install dependencies
+ run: npm ci
+ - name: Build Nest.js
+ run: npm run build
+ test_jest:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+ registry-url: 'https://registry.npmjs.org'
+ cache-dependency-path: package-lock.json
+ - name: Install dependencies
+ run: npm ci
+ - name: Run Jest
+ run: npm run test
+ check_licenses:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+ registry-url: 'https://registry.npmjs.org'
+ cache-dependency-path: package-lock.json
+ - name: Install dependencies
+ run: npm ci
+ - name: License Check
+ # List all the licenses and error out if it is not one of the supported licenses
+ run: npx license-report --fields=name --fields=licenseType | jq 'map(select(.licenseType | IN("MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "BSD-2-Clause") | not)) | if length == 0 then halt else halt_error(1) end'
diff --git a/services/content-watcher/.github/workflows/common/is-full-release/action.yml b/services/content-watcher/.github/workflows/common/is-full-release/action.yml
new file mode 100644
index 00000000..9e17770c
--- /dev/null
+++ b/services/content-watcher/.github/workflows/common/is-full-release/action.yml
@@ -0,0 +1,22 @@
+name: Is Full Release?
+description: Determines whether the version tag represents a full release
+inputs:
+ version-tag:
+ description: "Version tag in v#.#.#[-*] format"
+ required: true
+outputs:
+ is-full-release:
+ description: "'true' if full release, 'false' otherwise"
+ value: ${{steps.is-full-release.outputs.is_full_release}}
+runs:
+ using: "composite"
+ steps:
+ - name: Full Release?
+ id: is-full-release
+ shell: bash
+ run: |
+ version_tag=${{inputs.version-tag}}
+ is_full_release=$([[ "$version_tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && \
+ echo 'true' || echo 'false')
+ echo "is_full_release: $is_full_release"
+ echo "is_full_release=$is_full_release" >> $GITHUB_OUTPUT
diff --git a/services/content-watcher/.github/workflows/release.yml b/services/content-watcher/.github/workflows/release.yml
new file mode 100644
index 00000000..3f2f7c90
--- /dev/null
+++ b/services/content-watcher/.github/workflows/release.yml
@@ -0,0 +1,99 @@
+name: Release
+run-name: Cut Release ${{github.event.inputs.release-version || github.ref_name}}
+concurrency:
+ group: ${{github.workflow}}-${{github.ref}}
+ cancel-in-progress: true
+on:
+ push:
+ tags:
+ - 'v[0-9]+.[0-9]+.[0-9]+' # ex. v1.0.0
+ - 'v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+' # ex. v1.1.0-rc1
+ - 'v0.0.1' # used for testing only
+ - 'v0.0.1-rc[0-9]+' # used for testing only
+ workflow_dispatch:
+ inputs:
+ release-version:
+ description: 'Release version (v#.#.#[-rc#])'
+ required: true
+
+env:
+ NEW_RELEASE_TAG_FROM_UI: ${{github.event.inputs.release-version}}
+ TEST_RUN: ${{startsWith(github.event.inputs.release-version || github.ref_name, 'v0.0.1')}}
+ DOCKER_HUB_PROFILE: amplicalabs
+ IMAGE_NAME: content-publishing-service
+
+jobs:
+ build-and-publish-container-image:
+ name: Build and publish container image
+ runs-on: ubuntu-20.04
+ container: ghcr.io/libertydsnp/frequency/ci-base-image
+ steps:
+ - name: Validate Version Tag
+ if: env.NEW_RELEASE_TAG_FROM_UI != ''
+ shell: bash
+ run: |
+ version=${{env.NEW_RELEASE_TAG_FROM_UI}}
+ echo "Release version entered in UI: $version"
+ regex='^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-rc[1-9]\d*)?$'
+ if [[ ! $version =~ $regex ]]; then
+ echo "ERROR: Entered version $version is not valid."
+ echo "Please use v#.#.#[-rc#] format."
+ exit 1
+ fi
+ echo "valid-version=true" >> $GITHUB_OUTPUT
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ ref: ${{env.NEW_RELEASE_TAG_FROM_UI}}
+ - name: Set up tags for standalone image
+ id: standalone-tags
+ uses: docker/metadata-action@v4
+ with:
+ flavor: |
+ latest=auto
+ prefix=standalone-,onlatest=true
+ images: |
+ ${{env.DOCKER_HUB_PROFILE}}/${{env.IMAGE_NAME}}
+ tags: |
+ type=semver,pattern={{version}}
+ - name: Set up tags for app-only image
+ id: app-only-tags
+ uses: docker/metadata-action@v4
+ with:
+ flavor: |
+ latest=auto
+ prefix=apponly-,onlatest=true
+ images: |
+ ${{env.DOCKER_HUB_PROFILE}}/${{env.IMAGE_NAME}}
+ tags: |
+ type=semver,pattern={{version}}
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v2
+ with:
+ platforms: |
+ linux/amd64
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+ - name: Login to DockerHub
+ uses: docker/login-action@v2
+ with:
+ username: ${{secrets.DOCKERHUB_USERNAME_FC}}
+ password: ${{secrets.DOCKERHUB_TOKEN_FC}}
+ - name: Build and Push Standalone (Complete) Container Image
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ platforms: linux/amd64
+ push: ${{env.TEST_RUN != 'true'}}
+ file: ./Dockerfile
+ target: standalone
+ tags: ${{ steps.standalone-tags.outputs.tags }}
+ - name: Build and Push App-Only Container Image
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ platforms: linux/amd64
+ push: ${{env.TEST_RUN != 'true'}}
+ file: ./Dockerfile
+ target: app-only
+ tags: ${{ steps.app-only-tags.outputs.tags }}
diff --git a/services/content-watcher/.gitignore b/services/content-watcher/.gitignore
new file mode 100644
index 00000000..b1b73f10
--- /dev/null
+++ b/services/content-watcher/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+dist
+.env*
+.vscode
+coverage
diff --git a/services/content-watcher/.prettierrc b/services/content-watcher/.prettierrc
new file mode 100644
index 00000000..8a1a0966
--- /dev/null
+++ b/services/content-watcher/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "semi": true,
+ "trailingComma": "all",
+ "singleQuote": true,
+ "printWidth": 180,
+ "tabWidth": 2,
+ "useTabs": false
+}
diff --git a/services/content-watcher/.tool-versions b/services/content-watcher/.tool-versions
new file mode 100644
index 00000000..8ead549e
--- /dev/null
+++ b/services/content-watcher/.tool-versions
@@ -0,0 +1 @@
+nodejs 18.16.0
diff --git a/services/content-watcher/Dockerfile b/services/content-watcher/Dockerfile
new file mode 100644
index 00000000..3135bdae
--- /dev/null
+++ b/services/content-watcher/Dockerfile
@@ -0,0 +1,32 @@
+FROM --platform=linux/amd64 node:18 as build
+
+# TODO: The deployment docker image should install the content publishing
+# service from NPM rather than building from source
+WORKDIR /app
+COPY package*.json ./
+RUN npm install
+
+# Build / Copy the rest of the application files to the container and build
+COPY . .
+RUN npm run build
+
+FROM build as app-only
+
+EXPOSE 3000
+
+ENTRYPOINT npm start
+
+FROM build as standalone
+
+# Install Redis on top of the base image
+RUN apt-get -y update
+RUN apt-get -y install redis
+RUN sed -e 's/^appendonly .*$/appendonly yes/' /etc/redis/redis.conf > /etc/redis/redis.conf.appendonly
+RUN mv /etc/redis/redis.conf.appendonly /etc/redis/redis.conf
+
+ENV REDIS_URL=redis://localhost:6379
+
+VOLUME [ "/var/lib/redis" ]
+
+# Start the application
+ENTRYPOINT service redis-server start && npm start
diff --git a/services/content-watcher/INSTALLING.md b/services/content-watcher/INSTALLING.md
new file mode 100644
index 00000000..4112867f
--- /dev/null
+++ b/services/content-watcher/INSTALLING.md
@@ -0,0 +1,72 @@
+# INSTALLING
+
+## A Note about Redis Persistence
+
+The application requires a Redis server that is configured with `Append-only file` persistence. This is so that application state can be maintained across Redis restarts. Notes on how to configure this are included below for each type of deployment.
+
+
+## Deploying using prebuilt Docker images
+
+### Standalone (complete) image
+
+The standalone container image is meant to be a complete solution for a provider. It contains a single instance of the main application, plus a pre-configured Redis server. Simply download the latest [container image](https://hub.docker.com/r/amplicalabs/content-publishing-service/) and deploy using your favorite container management system.
+```
+ docker pull amplicalabs/content-publishing-service:standalone-latest
+```
+
+The internal Redis server included in the complete image is already configured for persistence; it is simply necessary to configure your container pod to map the directory `/var/lib/redis` to a persistent storage volume.
+
+#### Note: The internal redis server runs as user:group 100:102, so mapped volume permissions must at minimum allow write access to this user. How this is provisioned will depend on the specifics of your persistent storage infrastructure. If this is not configured properly, the redis server will fail to start, and the application upon launch will throw `ECONNREFUSED` errors.
+
+Follow the instructions below for [configuration](#configuration), with the exception that you should _not_ modify `REDIS_URL`, as it already points to the internal Redis server.
+
+### App-only image
+
+The app-only image is meant to be used for providers who would rather utilize a Redis instance in their own (or their cloud infrastructure provider's) external Redis instance or service. To download the latest [container image](https://hub.docker.com/r/amplicalabs/content-publishing-service/), simply:
+```
+ docker pull amplicalabs/content-publishing-service:apponly-latest
+```
+In this case, you need to ensure that the following settings are configured in your Redis instance:
+```
+appendonly true
+dir
+appendonlydir
+```
+
+You must also minimally map `appendonlydir` (or the entire `dir`) to a persistent storage volume in your infrastructure environment
+
+## Building and Deploying the Application
+
+If you choose to build & deploy the application yourself, simply install the prerequisites:
+* NodeJS 18
+
+Note that, at present, due to limitaions in the `@dsnp/graph-sdk` module, the applcation can only be run on a `linux/amd64` platform. Support for other platforms is contingent on building & installing the `@dsnp/graph-sdk` module from source, which is outside the scope of this document.
+
+To build the application:
+```
+ npm run build
+```
+
+To run the application:
+```
+ npm start
+```
+
+## Configuration
+
+For the application to start & run correctly, it is necessary to configure the environment with certain parameters. These should be injected into a container pod if running in a containerized environment.
+
+The following is a list of environment variables that may be set to control the application's behavior and environment. The complete list can always be referenced [here](./env.template)
+
+|Variable|required?|Description|Default|
+|-|-|-|-|
+|`FREQUENCY_URL`|**yes**|Blockchain URL|_none_|
+|`PROVIDER_ID`|**yes**|MSA ID of provider|_none_|
+|`PROVIDER_BASE_URL`|**yes**|URL of provider graph query endpoint|_none_|
+|`PROVIDER_ACCESS_TOKEN`|no|Optional access token to be used with requests to provider graph query endpoint|_none_|
+|`PROVIDER_ACCOUNT_SEED_PHRASE`|**yes**|Seed phrase for provider control keypair|_none_|
+|`REDIS_URL`|**yes**|URL used to connect to Redis instance|_none_
\*preset to the internal Redis URL in the standalone container|
+|`BLOCKCHAIN_SCAN_INTERVAL_MINUTES`|no|# of minutes to wait in between scans of the blockchain|180|
+|`QUEUE_HIGH_WATER`|no|# of pending graph scan queue entries to allow before pausing blockchain scanning until the next scan cycle|1000|
+|`GRAPH_ENVIRONMENT_TYPE`|**yes**|Indicates which blockchain network to connect to.
Possible values:
* `Mainnet`
* `Rococo`
* `Dev`|_none_|
+|`GRAPH_ENVIRONMENT_DEV_CONFIG`|no
*required for 'Dev' Graph Environment|JSON configuration object for GraphSDK configuration. Used to test against a local development Frequency node|_none_|
diff --git a/services/content-watcher/README.md b/services/content-watcher/README.md
index 728b40be..cfcb7194 100644
--- a/services/content-watcher/README.md
+++ b/services/content-watcher/README.md
@@ -1,2 +1,3 @@
-# content-publishing-service
-A microservice to publish DSNP content to frequency
+# Content Publisher
+
+A microservice to publish DSNP content to frequency.
diff --git a/services/content-watcher/dev.Dockerfile b/services/content-watcher/dev.Dockerfile
new file mode 100644
index 00000000..75173082
--- /dev/null
+++ b/services/content-watcher/dev.Dockerfile
@@ -0,0 +1,6 @@
+FROM node:18-alpine3.17
+
+WORKDIR /app
+
+# Start the application
+CMD ["npm", "run", "start:dev:docker"]
diff --git a/services/content-watcher/docker-compose.dev.yaml b/services/content-watcher/docker-compose.dev.yaml
new file mode 100644
index 00000000..f00d6080
--- /dev/null
+++ b/services/content-watcher/docker-compose.dev.yaml
@@ -0,0 +1,38 @@
+version: '3'
+
+services:
+ content-publishing-service:
+ build:
+ context: .
+ dockerfile: dev.Dockerfile
+ ports:
+ - 3000:3000
+ env_file:
+ - .env.docker.dev
+ volumes:
+ - ./:/app
+ networks:
+ - content-publishing-service-network-dev
+
+ redis:
+ image: redis:latest
+ ports:
+ - 6379:6379
+ networks:
+ - content-publishing-service-network-dev
+ volumes:
+ - redis_data:/data
+
+ frequency:
+ image: frequencychain/instant-seal-node:latest
+ ports:
+ - 9944:9944
+ networks:
+ - content-publishing-service-network-dev
+ container_name: frequency-node
+
+volumes:
+ redis_data:
+
+networks:
+ content-publishing-service-network-dev:
diff --git a/services/content-watcher/env.template b/services/content-watcher/env.template
new file mode 100644
index 00000000..410c1410
--- /dev/null
+++ b/services/content-watcher/env.template
@@ -0,0 +1,18 @@
+# Copy this file to ".env.dev" and ".env.docker.dev", and then tweak values for local development
+FREQUENCY_URL=ws://0.0.0.0:9944
+PROVIDER_ID=1
+PROVIDER_BASE_URL=https://some-provider/api/v1.0.0
+REDIS_URL=redis://0.0.0.0:6379
+PROVIDER_ACCESS_TOKEN=some-token
+BLOCKCHAIN_SCAN_INTERVAL_MINUTES=1
+QUEUE_HIGH_WATER=1000
+PROVIDER_ACCOUNT_SEED_PHRASE='come finish flower cinnamon blame year glad tank domain hunt release fatigue'
+WEBHOOK_FAILURE_THRESHOLD=3
+HEALTH_CHECK_SUCCESS_THRESHOLD=10
+WEBHOOK_RETRY_INTERVAL_SECONDS=10
+HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS=10
+HEALTH_CHECK_MAX_RETRIES=4
+CAPACITY_LIMIT='{"type":"percentage", "value":80}'
+
+# An optional bearer token may be specified for provider authentication
+PROVIDER_ACCESS_TOKEN=some-token
diff --git a/services/content-watcher/jest.config.js b/services/content-watcher/jest.config.js
new file mode 100644
index 00000000..7eb5e95a
--- /dev/null
+++ b/services/content-watcher/jest.config.js
@@ -0,0 +1,7 @@
+/** @type {import('ts-jest').JestConfigWithTsJest} */
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'node',
+ setupFiles: ["dotenv/config"],
+ testPathIgnorePatterns: ['/dist']
+};
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
new file mode 100644
index 00000000..1f9f486e
--- /dev/null
+++ b/services/content-watcher/package-lock.json
@@ -0,0 +1,9649 @@
+{
+ "name": "content-publishing-service",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "content-publishing-service",
+ "version": "1.0.0",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@dsnp/graph-sdk": "^0.0.11",
+ "@frequency-chain/api-augment": "1.7.0",
+ "@liaoliaots/nestjs-redis": "^9.0.5",
+ "@nestjs/axios": "^2.0.0",
+ "@nestjs/bullmq": "^10.0.0",
+ "@nestjs/common": "^9.4.0",
+ "@nestjs/config": "^2.3.1",
+ "@nestjs/core": "^9.4.0",
+ "@nestjs/event-emitter": "^1.4.1",
+ "@nestjs/platform-express": "^9.4.0",
+ "@nestjs/schedule": "^3.0.1",
+ "@nestjs/testing": "^9.4.0",
+ "@nestjs/typeorm": "^9.0.1",
+ "@polkadot/api": "^10.9.1",
+ "@polkadot/api-base": "^10.9.1",
+ "@polkadot/keyring": "^12.3.2",
+ "@polkadot/types": "^10.9.1",
+ "@polkadot/util": "^12.3.2",
+ "@polkadot/util-crypto": "^12.3.2",
+ "axios": "^1.3.6",
+ "bullmq": "^3.0.0",
+ "class-transformer": "^0.5.1",
+ "class-validator": "^0.14.0",
+ "ioredis": "^5.3.2",
+ "joi": "^17.9.1",
+ "rxjs": "^7.8.1",
+ "time-constants": "^1.0.3"
+ },
+ "devDependencies": {
+ "@jest/globals": "^29.5.0",
+ "@polkadot/typegen": "10.9.1",
+ "@types/jest": "^29.5.2",
+ "@types/time-constants": "^1.0.0",
+ "@typescript-eslint/parser": "^5.59.8",
+ "@typescript-eslint/typescript-estree": "5.59.8",
+ "dotenv": "^16.3.1",
+ "eslint": "^8.42.0",
+ "eslint-config-airbnb-base": "^15.0.0",
+ "eslint-config-airbnb-typescript": "^17.0.0",
+ "eslint-config-prettier": "^8.8.0",
+ "eslint-import-resolver-typescript": "^3.5.5",
+ "eslint-plugin-import": "^2.27.5",
+ "eslint-plugin-n": "^15.7.0",
+ "eslint-plugin-nestjs": "^1.2.3",
+ "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-promise": "^6.1.1",
+ "license-report": "^6.4.0",
+ "ts-jest": "^29.1.0",
+ "ts-node": "^10.9.1",
+ "ts-node-dev": "^2.0.0",
+ "tsconfig-paths": "^4.2.0",
+ "typescript": "^5.1.3"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/highlight": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.22.5",
+ "@babel/generator": "^7.22.5",
+ "@babel/helper-compilation-targets": "^7.22.5",
+ "@babel/helper-module-transforms": "^7.22.5",
+ "@babel/helpers": "^7.22.5",
+ "@babel/parser": "^7.22.5",
+ "@babel/template": "^7.22.5",
+ "@babel/traverse": "^7.22.5",
+ "@babel/types": "^7.22.5",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.22.5",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.5",
+ "@babel/helper-validator-option": "^7.22.5",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.22.5",
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.5",
+ "@babel/helper-module-imports": "^7.22.5",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/template": "^7.22.5",
+ "@babel/traverse": "^7.22.5",
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.22.5",
+ "@babel/traverse": "^7.22.5",
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.22.3",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "regenerator-runtime": "^0.13.11"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.22.5",
+ "@babel/parser": "^7.22.5",
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.22.5",
+ "@babel/generator": "^7.22.5",
+ "@babel/helper-environment-visitor": "^7.22.5",
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.5",
+ "@babel/parser": "^7.22.5",
+ "@babel/types": "^7.22.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.22.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@dsnp/graph-sdk": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/@dsnp/graph-sdk/-/graph-sdk-0.0.11.tgz",
+ "integrity": "sha512-GQJ+gnXLku1HyyVJfHM4CgMtv0GAi00jhNVnPlmhe5bMwkfj6Pg1ZCS8/fKgRiu8G5PAVGGCSInA/2iyBZC33g==",
+ "engines": {
+ "node": "^14.0.0 || ^16.0.0 || >=17.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.5.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.5.2",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.42.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@frequency-chain/api-augment": {
+ "version": "1.7.0",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/api": "^10.7.3",
+ "@polkadot/rpc-provider": "^10.7.3",
+ "@polkadot/types": "^10.7.3"
+ }
+ },
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.10",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@ioredis/commands": {
+ "version": "1.2.0",
+ "license": "MIT"
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/console": "^29.5.0",
+ "@jest/reporters": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.5.0",
+ "jest-config": "^29.5.0",
+ "jest-haste-map": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-resolve-dependencies": "^29.5.0",
+ "jest-runner": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
+ "jest-watcher": "^29.5.0",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.5.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "jest-mock": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.5.0",
+ "jest-snapshot": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.4.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.5.0",
+ "jest-mock": "^29.5.0",
+ "jest-util": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.5.0",
+ "@jest/expect": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "jest-mock": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-worker": "^29.5.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.25.16"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jest/source-map/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/console": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/test-result": "^29.5.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.5.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.5.0",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-util": "^29.5.0",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.2"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jest/transform/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.4.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@kessler/tableify": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@liaoliaots/nestjs-redis": {
+ "version": "9.0.5",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2.4.1"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^9.0.0",
+ "@nestjs/core": "^9.0.0",
+ "ioredis": "^5.0.0"
+ }
+ },
+ "node_modules/@liaoliaots/nestjs-redis/node_modules/tslib": {
+ "version": "2.4.1",
+ "license": "0BSD"
+ },
+ "node_modules/@lukeed/csprng": {
+ "version": "1.1.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@nestjs/axios": {
+ "version": "2.0.0",
+ "license": "MIT",
+ "peerDependencies": {
+ "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0",
+ "axios": "^1.3.1",
+ "reflect-metadata": "^0.1.12",
+ "rxjs": "^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/@nestjs/bull-shared": {
+ "version": "10.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2.5.3"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0"
+ }
+ },
+ "node_modules/@nestjs/bullmq": {
+ "version": "10.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "@nestjs/bull-shared": "^10.0.0",
+ "tslib": "2.5.3"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "bullmq": "^3.0.0"
+ }
+ },
+ "node_modules/@nestjs/common": {
+ "version": "9.4.3",
+ "license": "MIT",
+ "dependencies": {
+ "iterare": "1.2.1",
+ "tslib": "2.5.3",
+ "uid": "2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "cache-manager": "<=5",
+ "class-transformer": "*",
+ "class-validator": "*",
+ "reflect-metadata": "^0.1.12",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "cache-manager": {
+ "optional": true
+ },
+ "class-transformer": {
+ "optional": true
+ },
+ "class-validator": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/config": {
+ "version": "2.3.3",
+ "license": "MIT",
+ "dependencies": {
+ "dotenv": "16.1.4",
+ "dotenv-expand": "10.0.0",
+ "lodash": "4.17.21",
+ "uuid": "9.0.0"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0",
+ "reflect-metadata": "^0.1.13",
+ "rxjs": "^6.0.0 || ^7.2.0"
+ }
+ },
+ "node_modules/@nestjs/config/node_modules/dotenv": {
+ "version": "16.1.4",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/motdotla/dotenv?sponsor=1"
+ }
+ },
+ "node_modules/@nestjs/core": {
+ "version": "9.4.3",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nuxtjs/opencollective": "0.3.2",
+ "fast-safe-stringify": "2.1.1",
+ "iterare": "1.2.1",
+ "path-to-regexp": "3.2.0",
+ "tslib": "2.5.3",
+ "uid": "2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^9.0.0",
+ "@nestjs/microservices": "^9.0.0",
+ "@nestjs/platform-express": "^9.0.0",
+ "@nestjs/websockets": "^9.0.0",
+ "reflect-metadata": "^0.1.12",
+ "rxjs": "^7.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@nestjs/microservices": {
+ "optional": true
+ },
+ "@nestjs/platform-express": {
+ "optional": true
+ },
+ "@nestjs/websockets": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/event-emitter": {
+ "version": "1.4.2",
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter2": "6.4.9"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0",
+ "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0",
+ "reflect-metadata": "^0.1.12"
+ }
+ },
+ "node_modules/@nestjs/platform-express": {
+ "version": "9.4.3",
+ "license": "MIT",
+ "dependencies": {
+ "body-parser": "1.20.2",
+ "cors": "2.8.5",
+ "express": "4.18.2",
+ "multer": "1.4.4-lts.1",
+ "tslib": "2.5.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^9.0.0",
+ "@nestjs/core": "^9.0.0"
+ }
+ },
+ "node_modules/@nestjs/schedule": {
+ "version": "3.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "cron": "2.3.1",
+ "uuid": "9.0.0"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "reflect-metadata": "^0.1.12"
+ }
+ },
+ "node_modules/@nestjs/testing": {
+ "version": "9.4.3",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2.5.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nest"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^9.0.0",
+ "@nestjs/core": "^9.0.0",
+ "@nestjs/microservices": "^9.0.0",
+ "@nestjs/platform-express": "^9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@nestjs/microservices": {
+ "optional": true
+ },
+ "@nestjs/platform-express": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/typeorm": {
+ "version": "9.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "uuid": "8.3.2"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^8.0.0 || ^9.0.0",
+ "@nestjs/core": "^8.0.0 || ^9.0.0",
+ "reflect-metadata": "^0.1.13",
+ "rxjs": "^7.2.0",
+ "typeorm": "^0.3.0"
+ }
+ },
+ "node_modules/@nestjs/typeorm/node_modules/uuid": {
+ "version": "8.3.2",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/@noble/curves": {
+ "version": "1.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "1.3.1"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@noble/hashes": {
+ "version": "1.3.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective": {
+ "version": "0.3.2",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "consola": "^2.15.0",
+ "node-fetch": "^2.6.1"
+ },
+ "bin": {
+ "opencollective": "bin/opencollective.js"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/@nuxtjs/opencollective/node_modules/node-fetch": {
+ "version": "2.6.11",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@pkgr/utils": {
+ "version": "2.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "fast-glob": "^3.2.12",
+ "is-glob": "^4.0.3",
+ "open": "^9.1.0",
+ "picocolors": "^1.0.0",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/@polkadot/api": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/api-augment": "10.9.1",
+ "@polkadot/api-base": "10.9.1",
+ "@polkadot/api-derive": "10.9.1",
+ "@polkadot/keyring": "^12.3.1",
+ "@polkadot/rpc-augment": "10.9.1",
+ "@polkadot/rpc-core": "10.9.1",
+ "@polkadot/rpc-provider": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-augment": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/types-create": "10.9.1",
+ "@polkadot/types-known": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/util-crypto": "^12.3.1",
+ "eventemitter3": "^5.0.1",
+ "rxjs": "^7.8.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/api-augment": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/api-base": "10.9.1",
+ "@polkadot/rpc-augment": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-augment": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/api-base": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/rpc-core": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "rxjs": "^7.8.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/api-derive": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/api": "10.9.1",
+ "@polkadot/api-augment": "10.9.1",
+ "@polkadot/api-base": "10.9.1",
+ "@polkadot/rpc-core": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/util-crypto": "^12.3.1",
+ "rxjs": "^7.8.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/keyring": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/util": "12.3.2",
+ "@polkadot/util-crypto": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "12.3.2",
+ "@polkadot/util-crypto": "12.3.2"
+ }
+ },
+ "node_modules/@polkadot/networks": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/util": "12.3.2",
+ "@substrate/ss58-registry": "^1.40.0",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/rpc-augment": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/rpc-core": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/rpc-core": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/rpc-augment": "10.9.1",
+ "@polkadot/rpc-provider": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "rxjs": "^7.8.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/rpc-provider": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/keyring": "^12.3.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-support": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/util-crypto": "^12.3.1",
+ "@polkadot/x-fetch": "^12.3.1",
+ "@polkadot/x-global": "^12.3.1",
+ "@polkadot/x-ws": "^12.3.1",
+ "eventemitter3": "^5.0.1",
+ "mock-socket": "^9.2.1",
+ "nock": "^13.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "optionalDependencies": {
+ "@substrate/connect": "0.7.26"
+ }
+ },
+ "node_modules/@polkadot/typegen": {
+ "version": "10.9.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/api": "10.9.1",
+ "@polkadot/api-augment": "10.9.1",
+ "@polkadot/rpc-augment": "10.9.1",
+ "@polkadot/rpc-provider": "10.9.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-augment": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/types-create": "10.9.1",
+ "@polkadot/types-support": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/util-crypto": "^12.3.1",
+ "@polkadot/x-ws": "^12.3.1",
+ "handlebars": "^4.7.7",
+ "tslib": "^2.5.3",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "polkadot-types-chain-info": "scripts/polkadot-types-chain-info.mjs",
+ "polkadot-types-from-chain": "scripts/polkadot-types-from-chain.mjs",
+ "polkadot-types-from-defs": "scripts/polkadot-types-from-defs.mjs",
+ "polkadot-types-internal-interfaces": "scripts/polkadot-types-internal-interfaces.mjs",
+ "polkadot-types-internal-metadata": "scripts/polkadot-types-internal-metadata.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/keyring": "^12.3.1",
+ "@polkadot/types-augment": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/types-create": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/util-crypto": "^12.3.1",
+ "rxjs": "^7.8.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-augment": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-codec": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/util": "^12.3.1",
+ "@polkadot/x-bigint": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-codec/node_modules/@polkadot/x-bigint": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-create": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-known": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/networks": "^12.3.1",
+ "@polkadot/types": "10.9.1",
+ "@polkadot/types-codec": "10.9.1",
+ "@polkadot/types-create": "10.9.1",
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/types-support": {
+ "version": "10.9.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/util": "^12.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/util": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-bigint": "12.3.2",
+ "@polkadot/x-global": "12.3.2",
+ "@polkadot/x-textdecoder": "12.3.2",
+ "@polkadot/x-textencoder": "12.3.2",
+ "@types/bn.js": "^5.1.1",
+ "bn.js": "^5.2.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/util-crypto": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@noble/curves": "1.1.0",
+ "@noble/hashes": "1.3.1",
+ "@polkadot/networks": "12.3.2",
+ "@polkadot/util": "12.3.2",
+ "@polkadot/wasm-crypto": "^7.2.1",
+ "@polkadot/wasm-util": "^7.2.1",
+ "@polkadot/x-bigint": "12.3.2",
+ "@polkadot/x-randomvalues": "12.3.2",
+ "@scure/base": "1.1.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "12.3.2"
+ }
+ },
+ "node_modules/@polkadot/util-crypto/node_modules/@polkadot/wasm-bridge": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/wasm-util": "7.2.1",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*",
+ "@polkadot/x-randomvalues": "*"
+ }
+ },
+ "node_modules/@polkadot/util-crypto/node_modules/@polkadot/wasm-crypto": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/wasm-bridge": "7.2.1",
+ "@polkadot/wasm-crypto-asmjs": "7.2.1",
+ "@polkadot/wasm-crypto-init": "7.2.1",
+ "@polkadot/wasm-crypto-wasm": "7.2.1",
+ "@polkadot/wasm-util": "7.2.1",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*",
+ "@polkadot/x-randomvalues": "*"
+ }
+ },
+ "node_modules/@polkadot/util-crypto/node_modules/@polkadot/wasm-crypto-init": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/wasm-bridge": "7.2.1",
+ "@polkadot/wasm-crypto-asmjs": "7.2.1",
+ "@polkadot/wasm-crypto-wasm": "7.2.1",
+ "@polkadot/wasm-util": "7.2.1",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*",
+ "@polkadot/x-randomvalues": "*"
+ }
+ },
+ "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-bigint": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/util/node_modules/@polkadot/x-bigint": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/wasm-crypto-asmjs": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*"
+ }
+ },
+ "node_modules/@polkadot/wasm-crypto-wasm": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/wasm-util": "7.2.1",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*"
+ }
+ },
+ "node_modules/@polkadot/wasm-util": {
+ "version": "7.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "*"
+ }
+ },
+ "node_modules/@polkadot/x-fetch": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "node-fetch": "^3.3.1",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/x-global": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/x-randomvalues": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "@polkadot/util": "12.3.2",
+ "@polkadot/wasm-util": "*"
+ }
+ },
+ "node_modules/@polkadot/x-textdecoder": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/x-textencoder": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@polkadot/x-ws": {
+ "version": "12.3.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polkadot/x-global": "12.3.2",
+ "tslib": "^2.5.3",
+ "ws": "^8.13.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@redis/bloom": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.5.8",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.1.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.4",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.1.3",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.0.4",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@scure/base": {
+ "version": "1.1.1",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@sideway/address": {
+ "version": "4.1.4",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.25.24",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "5.4.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "10.1.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0"
+ }
+ },
+ "node_modules/@sqltools/formatter": {
+ "version": "1.2.5",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@substrate/connect": {
+ "version": "0.7.26",
+ "license": "GPL-3.0-only",
+ "optional": true,
+ "dependencies": {
+ "@substrate/connect-extension-protocol": "^1.0.1",
+ "eventemitter3": "^4.0.7",
+ "smoldot": "1.0.4"
+ }
+ },
+ "node_modules/@substrate/connect-extension-protocol": {
+ "version": "1.0.1",
+ "license": "GPL-3.0-only",
+ "optional": true
+ },
+ "node_modules/@substrate/connect/node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@substrate/ss58-registry": {
+ "version": "1.40.0",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defer-to-connect": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.4",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/bn.js": {
+ "version": "5.1.1",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "29.5.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.0.0",
+ "pretty-format": "^29.0.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.12",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.2.5",
+ "license": "MIT"
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.7.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/semver": {
+ "version": "7.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/strip-bom": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/strip-json-comments": {
+ "version": "0.0.30",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/time-constants": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/validator": {
+ "version": "13.7.17",
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.24",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.4.0",
+ "@typescript-eslint/scope-manager": "5.59.11",
+ "@typescript-eslint/type-utils": "5.59.11",
+ "@typescript-eslint/utils": "5.59.11",
+ "debug": "^4.3.4",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^5.0.0",
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "5.59.9",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "5.59.9",
+ "@typescript-eslint/types": "5.59.9",
+ "@typescript-eslint/typescript-estree": "5.59.9",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.59.9",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.9",
+ "@typescript-eslint/visitor-keys": "5.59.9",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "5.59.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.9",
+ "@typescript-eslint/visitor-keys": "5.59.9"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "5.59.11",
+ "@typescript-eslint/utils": "5.59.11",
+ "debug": "^4.3.4",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "5.59.9",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.59.8",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.8",
+ "@typescript-eslint/visitor-keys": "5.59.8",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/types": {
+ "version": "5.59.8",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.59.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.8",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@types/json-schema": "^7.0.9",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.59.11",
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/typescript-estree": "5.59.11",
+ "eslint-scope": "^5.1.1",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.59.11",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.11",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.59.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "5.59.9",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "devOptional": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/app-root-path": {
+ "version": "3.1.0",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/append-field": {
+ "version": "1.0.0",
+ "license": "MIT"
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "license": "MIT"
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "get-intrinsic": "^1.1.3",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/async": {
+ "version": "3.2.3",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "license": "MIT"
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.4.0",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/babel-jest": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/transform": "^29.5.0",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.5.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.5.0",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/big-integer": {
+ "version": "1.6.51",
+ "dev": true,
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bn.js": {
+ "version": "5.2.1",
+ "license": "MIT"
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.2",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "license": "MIT"
+ },
+ "node_modules/bplist-parser": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big-integer": "^1.6.44"
+ },
+ "engines": {
+ "node": ">= 5.10.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.8",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001502",
+ "electron-to-chromium": "^1.4.428",
+ "node-releases": "^2.0.12",
+ "update-browserslist-db": "^1.0.11"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "license": "MIT"
+ },
+ "node_modules/builtins": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
+ },
+ "node_modules/bullmq": {
+ "version": "3.15.8",
+ "license": "MIT",
+ "dependencies": {
+ "cron-parser": "^4.6.0",
+ "glob": "^8.0.3",
+ "ioredis": "^5.3.2",
+ "lodash": "^4.17.21",
+ "msgpackr": "^1.6.2",
+ "semver": "^7.3.7",
+ "tslib": "^2.0.0",
+ "uuid": "^9.0.0"
+ }
+ },
+ "node_modules/bullmq/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/bullmq/node_modules/glob": {
+ "version": "8.1.0",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/bullmq/node_modules/minimatch": {
+ "version": "5.1.6",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/bundle-name": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cache-manager": {
+ "version": "4.1.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "async": "3.2.3",
+ "lodash.clonedeep": "^4.5.0",
+ "lru-cache": "^7.10.1"
+ }
+ },
+ "node_modules/cache-manager/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "license": "ISC",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "7.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "10.2.12",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-cache-semantics": "^4.0.1",
+ "get-stream": "^6.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "keyv": "^4.5.2",
+ "mimic-response": "^4.0.0",
+ "normalize-url": "^8.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001502",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.8.0",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/class-transformer": {
+ "version": "0.5.1",
+ "license": "MIT"
+ },
+ "node_modules/class-validator": {
+ "version": "0.14.0",
+ "license": "MIT",
+ "dependencies": {
+ "@types/validator": "^13.7.10",
+ "libphonenumber-js": "^1.10.14",
+ "validator": "^13.7.0"
+ }
+ },
+ "node_modules/cli-highlight": {
+ "version": "2.1.11",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "highlight.js": "^10.7.1",
+ "mz": "^2.4.0",
+ "parse5": "^5.1.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.0",
+ "yargs": "^16.0.0"
+ },
+ "bin": {
+ "highlight": "bin/highlight"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/cliui": {
+ "version": "7.0.4",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/yargs": {
+ "version": "16.2.0",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/confusing-browser-globals": {
+ "version": "1.0.11",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "2.15.3",
+ "license": "MIT"
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.5.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/cron": {
+ "version": "2.3.1",
+ "license": "MIT",
+ "dependencies": {
+ "luxon": "^3.2.1"
+ }
+ },
+ "node_modules/cron-parser": {
+ "version": "4.8.1",
+ "license": "MIT",
+ "dependencies": {
+ "luxon": "^3.2.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/date-fns": {
+ "version": "2.30.0",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.21.0"
+ },
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dedent": {
+ "version": "0.7.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-browser": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^3.0.0",
+ "default-browser-id": "^3.0.0",
+ "execa": "^7.1.1",
+ "titleize": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bplist-parser": "^0.2.0",
+ "untildify": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "devOptional": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.3.1",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/motdotla/dotenv?sponsor=1"
+ }
+ },
+ "node_modules/dotenv-expand": {
+ "version": "10.0.0",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/dynamic-dedupe": {
+ "version": "0.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.429",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.14.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/eol": {
+ "version": "0.9.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.21.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.5",
+ "get-intrinsic": "^1.2.0",
+ "get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has": "^1.0.3",
+ "has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
+ "is-callable": "^1.2.7",
+ "is-negative-zero": "^2.0.2",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.12.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.4.3",
+ "safe-regex-test": "^1.0.0",
+ "string.prototype.trim": "^1.2.7",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.3"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.42.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.4.0",
+ "@eslint/eslintrc": "^2.0.3",
+ "@eslint/js": "8.42.0",
+ "@humanwhocodes/config-array": "^0.11.10",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.0",
+ "eslint-visitor-keys": "^3.4.1",
+ "espree": "^9.5.2",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "strip-ansi": "^6.0.1",
+ "strip-json-comments": "^3.1.0",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base": {
+ "version": "15.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confusing-browser-globals": "^1.0.10",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.32.0 || ^8.2.0",
+ "eslint-plugin-import": "^2.25.2"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-config-airbnb-typescript": {
+ "version": "17.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-config-airbnb-base": "^15.0.0"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/eslint-plugin": "^5.13.0",
+ "@typescript-eslint/parser": "^5.0.0",
+ "eslint": "^7.32.0 || ^8.2.0",
+ "eslint-plugin-import": "^2.25.3"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "8.8.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.11.0",
+ "resolve": "^1.22.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "3.5.5",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "enhanced-resolve": "^5.12.0",
+ "eslint-module-utils": "^2.7.4",
+ "get-tsconfig": "^4.5.0",
+ "globby": "^13.1.3",
+ "is-core-module": "^2.11.0",
+ "is-glob": "^4.0.3",
+ "synckit": "^0.8.5"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript/node_modules/globby": {
+ "version": "13.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.11",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript/node_modules/slash": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.8.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-es": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=4.19.1"
+ }
+ },
+ "node_modules/eslint-plugin-es/node_modules/eslint-utils": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.27.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.7.4",
+ "has": "^1.0.3",
+ "is-core-module": "^2.11.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.values": "^1.1.6",
+ "resolve": "^1.22.1",
+ "semver": "^6.3.0",
+ "tsconfig-paths": "^3.14.1"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/json5": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": {
+ "version": "3.14.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-n": {
+ "version": "15.7.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "builtins": "^5.0.1",
+ "eslint-plugin-es": "^4.1.0",
+ "eslint-utils": "^3.0.0",
+ "ignore": "^5.1.1",
+ "is-core-module": "^2.11.0",
+ "minimatch": "^3.1.2",
+ "resolve": "^1.22.1",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-nestjs": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "npm": ">=3"
+ }
+ },
+ "node_modules/eslint-plugin-nestjs/node_modules/tslib": {
+ "version": "1.14.1",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "4.2.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.28.0",
+ "prettier": ">=2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "6.1.1",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "7.2.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/estraverse": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.5.2",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter2": {
+ "version": "6.4.9",
+ "license": "MIT"
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "license": "MIT"
+ },
+ "node_modules/execa": {
+ "version": "7.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.1",
+ "human-signals": "^4.3.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^3.0.7",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || ^16.14.0 || >=18.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.18.2",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.1",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.11.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/body-parser": {
+ "version": "1.20.1",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "license": "MIT"
+ },
+ "node_modules/express/node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "license": "MIT"
+ },
+ "node_modules/express/node_modules/raw-body": {
+ "version": "2.5.1",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.12",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "license": "MIT"
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/form-data-encoder": {
+ "version": "2.1.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.17"
+ }
+ },
+ "node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "license": "MIT",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "license": "ISC"
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "license": "MIT"
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.19.0",
+ "functions-have-names": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generic-pool": {
+ "version": "3.9.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.1",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-stdin": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.6.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.20.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/got": {
+ "version": "12.6.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^5.2.0",
+ "@szmarczak/http-timer": "^5.0.1",
+ "cacheable-lookup": "^7.0.0",
+ "cacheable-request": "^10.2.8",
+ "decompress-response": "^6.0.0",
+ "form-data-encoder": "^2.1.2",
+ "get-stream": "^6.0.1",
+ "http2-wrapper": "^2.1.10",
+ "lowercase-keys": "^3.0.0",
+ "p-cancelable": "^3.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http2-wrapper": {
+ "version": "2.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "4.3.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14.18.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ioredis": {
+ "version": "5.3.2",
+ "license": "MIT",
+ "dependencies": {
+ "@ioredis/commands": "^1.1.1",
+ "cluster-key-slot": "^1.1.0",
+ "debug": "^4.3.4",
+ "denque": "^2.1.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.isarguments": "^3.1.0",
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0",
+ "standard-as-callback": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ioredis"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.12.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.10",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-wsl/node_modules/is-docker": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.5",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/iterare": {
+ "version": "1.2.1",
+ "license": "ISC",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/core": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.5.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/execa": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/human-signals": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/is-stream": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/onetime": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/environment": "^29.5.0",
+ "@jest/expect": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.5.0",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.5.0",
+ "pure-rand": "^6.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/core": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "babel-jest": "^29.5.0",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.5.0",
+ "jest-environment-node": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-runner": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.5.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.4.3",
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.4.3",
+ "jest-util": "^29.5.0",
+ "pretty-format": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/environment": "^29.5.0",
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "jest-mock": "^29.5.0",
+ "jest-util": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.4.3",
+ "jest-util": "^29.5.0",
+ "jest-worker": "^29.5.0",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.5.0",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.5.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "jest-util": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.4.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.5.0",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^2.0.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "jest-regex-util": "^29.4.3",
+ "jest-snapshot": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/console": "^29.5.0",
+ "@jest/environment": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.4.3",
+ "jest-environment-node": "^29.5.0",
+ "jest-haste-map": "^29.5.0",
+ "jest-leak-detector": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-resolve": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-watcher": "^29.5.0",
+ "jest-worker": "^29.5.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner/node_modules/source-map-support": {
+ "version": "0.5.13",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/environment": "^29.5.0",
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/globals": "^29.5.0",
+ "@jest/source-map": "^29.4.3",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-mock": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/strip-bom": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.5.0",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.5.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/types": "^29.5.0",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.4.3",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.5.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.5.0",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.5.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/joi": {
+ "version": "17.9.2",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0",
+ "@hapi/topo": "^5.0.0",
+ "@sideway/address": "^4.1.3",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "license": "ISC"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/libphonenumber-js": {
+ "version": "1.10.34",
+ "license": "MIT"
+ },
+ "node_modules/license-report": {
+ "version": "6.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@kessler/tableify": "^1.0.2",
+ "debug": "^4.3.4",
+ "eol": "^0.9.1",
+ "got": "^12.6.0",
+ "rc": "^1.2.8",
+ "semver": "^7.3.8",
+ "tablemark": "^3.0.0",
+ "text-table": "^0.2.0",
+ "visit-values": "^2.0.0"
+ },
+ "bin": {
+ "license-report": "index.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "license": "MIT"
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/lodash.defaults": {
+ "version": "4.2.0",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isarguments": {
+ "version": "3.1.0",
+ "license": "MIT"
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/luxon": {
+ "version": "3.3.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "devOptional": true,
+ "license": "ISC"
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "license": "MIT"
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mock-socket": {
+ "version": "9.2.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "license": "MIT"
+ },
+ "node_modules/msgpackr": {
+ "version": "1.9.5",
+ "license": "MIT",
+ "optionalDependencies": {
+ "msgpackr-extract": "^3.0.2"
+ }
+ },
+ "node_modules/msgpackr-extract": {
+ "version": "3.0.2",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-gyp-build-optional-packages": "5.0.7"
+ },
+ "bin": {
+ "download-msgpackr-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2",
+ "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2",
+ "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2",
+ "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2",
+ "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2",
+ "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2"
+ }
+ },
+ "node_modules/multer": {
+ "version": "1.4.4-lts.1",
+ "license": "MIT",
+ "dependencies": {
+ "append-field": "^1.0.0",
+ "busboy": "^1.0.0",
+ "concat-stream": "^1.5.2",
+ "mkdirp": "^0.5.4",
+ "object-assign": "^4.1.1",
+ "type-is": "^1.6.4",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-compare-lite": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/nock": {
+ "version": "13.3.1",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.0",
+ "json-stringify-safe": "^5.0.1",
+ "lodash": "^4.17.21",
+ "propagate": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13"
+ }
+ },
+ "node_modules/node-domexception": {
+ "version": "1.0.0",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "3.3.1",
+ "license": "MIT",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/node-gyp-build-optional-packages": {
+ "version": "5.0.7",
+ "license": "MIT",
+ "optional": true,
+ "bin": {
+ "node-gyp-build-optional-packages": "bin.js",
+ "node-gyp-build-optional-packages-optional": "optional.js",
+ "node-gyp-build-optional-packages-test": "build-test.js"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.12",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "8.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "5.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.3",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "9.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^4.0.0",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pako": {
+ "version": "2.1.0",
+ "license": "(MIT AND Zlib)",
+ "optional": true
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "5.1.1",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+ "version": "6.0.1",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "3.2.0",
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "29.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.4.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "license": "MIT"
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/propagate": {
+ "version": "2.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "license": "MIT"
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pure-rand": {
+ "version": "6.0.2",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/qs": {
+ "version": "6.11.0",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "dev": true,
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/redis": {
+ "version": "4.6.7",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "workspaces": [
+ "./packages/*"
+ ],
+ "dependencies": {
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.5.8",
+ "@redis/graph": "1.1.0",
+ "@redis/json": "1.0.4",
+ "@redis/search": "1.1.3",
+ "@redis/time-series": "1.0.4"
+ }
+ },
+ "node_modules/redis-errors": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/redis-parser": {
+ "version": "3.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "redis-errors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reflect-metadata": {
+ "version": "0.1.13",
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.11",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.11.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/resolve.exports": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lowercase-keys": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-applescript/node_modules/execa": {
+ "version": "5.1.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/run-applescript/node_modules/human-signals": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/run-applescript/node_modules/is-stream": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-applescript/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/run-applescript/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/run-applescript/node_modules/onetime": {
+ "version": "5.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-applescript/node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "is-regex": "^1.1.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.5.3",
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.18.0",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "license": "MIT"
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "license": "MIT"
+ },
+ "node_modules/sentence-case": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case-first": "^2.0.2"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.15.0",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "license": "ISC"
+ },
+ "node_modules/sha.js": {
+ "version": "2.4.11",
+ "license": "(MIT AND BSD-3-Clause)",
+ "peer": true,
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "bin": {
+ "sha.js": "bin.js"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/smoldot": {
+ "version": "1.0.4",
+ "license": "GPL-3.0-or-later WITH Classpath-exception-2.0",
+ "optional": true,
+ "dependencies": {
+ "pako": "^2.0.4",
+ "ws": "^8.8.1"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/split-text-to-chunks": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-stdin": "^5.0.1",
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "wordwrap": "cli.js"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/stack-utils/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/standard-as-callback": {
+ "version": "2.1.0",
+ "license": "MIT"
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/streamsearch": {
+ "version": "1.1.0",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "license": "MIT"
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.7",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/synckit": {
+ "version": "0.8.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/utils": "^2.3.1",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts"
+ }
+ },
+ "node_modules/tablemark": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sentence-case": "^3.0.4",
+ "split-text-to-chunks": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/time-constants": {
+ "version": "1.0.3",
+ "license": "ISC"
+ },
+ "node_modules/titleize": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "license": "MIT"
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/ts-jest": {
+ "version": "29.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs-logger": "0.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.3",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "^21.0.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/types": "^29.0.0",
+ "babel-jest": "^29.0.0",
+ "jest": "^29.0.0",
+ "typescript": ">=4.3 <6"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.1",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node-dev": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.1",
+ "dynamic-dedupe": "^0.3.0",
+ "minimist": "^1.2.6",
+ "mkdirp": "^1.0.4",
+ "resolve": "^1.0.0",
+ "rimraf": "^2.6.1",
+ "source-map-support": "^0.5.12",
+ "tree-kill": "^1.2.2",
+ "ts-node": "^10.4.0",
+ "tsconfig": "^7.0.0"
+ },
+ "bin": {
+ "ts-node-dev": "lib/bin.js",
+ "tsnd": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "*",
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node-dev/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-node-dev/node_modules/rimraf": {
+ "version": "2.7.1",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/tsconfig": {
+ "version": "7.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/strip-bom": "^3.0.0",
+ "@types/strip-json-comments": "0.0.30",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "^2.0.0"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "4.2.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json5": "^2.2.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tsconfig/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.5.3",
+ "license": "0BSD"
+ },
+ "node_modules/tsutils": {
+ "version": "3.21.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+ }
+ },
+ "node_modules/tsutils/node_modules/tslib": {
+ "version": "1.14.1",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "license": "MIT"
+ },
+ "node_modules/typeorm": {
+ "version": "0.3.16",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@sqltools/formatter": "^1.2.5",
+ "app-root-path": "^3.1.0",
+ "buffer": "^6.0.3",
+ "chalk": "^4.1.2",
+ "cli-highlight": "^2.1.11",
+ "date-fns": "^2.29.3",
+ "debug": "^4.3.4",
+ "dotenv": "^16.0.3",
+ "glob": "^8.1.0",
+ "mkdirp": "^2.1.3",
+ "reflect-metadata": "^0.1.13",
+ "sha.js": "^2.4.11",
+ "tslib": "^2.5.0",
+ "uuid": "^9.0.0",
+ "yargs": "^17.6.2"
+ },
+ "bin": {
+ "typeorm": "cli.js",
+ "typeorm-ts-node-commonjs": "cli-ts-node-commonjs.js",
+ "typeorm-ts-node-esm": "cli-ts-node-esm.js"
+ },
+ "engines": {
+ "node": ">= 12.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/typeorm"
+ },
+ "peerDependencies": {
+ "@google-cloud/spanner": "^5.18.0",
+ "@sap/hana-client": "^2.12.25",
+ "better-sqlite3": "^7.1.2 || ^8.0.0",
+ "hdb-pool": "^0.1.6",
+ "ioredis": "^5.0.4",
+ "mongodb": "^5.2.0",
+ "mssql": "^9.1.1",
+ "mysql2": "^2.2.5 || ^3.0.1",
+ "oracledb": "^5.1.0",
+ "pg": "^8.5.1",
+ "pg-native": "^3.0.0",
+ "pg-query-stream": "^4.0.0",
+ "redis": "^3.1.1 || ^4.0.0",
+ "sql.js": "^1.4.0",
+ "sqlite3": "^5.0.3",
+ "ts-node": "^10.7.0",
+ "typeorm-aurora-data-api-driver": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@google-cloud/spanner": {
+ "optional": true
+ },
+ "@sap/hana-client": {
+ "optional": true
+ },
+ "better-sqlite3": {
+ "optional": true
+ },
+ "hdb-pool": {
+ "optional": true
+ },
+ "ioredis": {
+ "optional": true
+ },
+ "mongodb": {
+ "optional": true
+ },
+ "mssql": {
+ "optional": true
+ },
+ "mysql2": {
+ "optional": true
+ },
+ "oracledb": {
+ "optional": true
+ },
+ "pg": {
+ "optional": true
+ },
+ "pg-native": {
+ "optional": true
+ },
+ "pg-query-stream": {
+ "optional": true
+ },
+ "redis": {
+ "optional": true
+ },
+ "sql.js": {
+ "optional": true
+ },
+ "sqlite3": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ },
+ "typeorm-aurora-data-api-driver": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/typeorm/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/typeorm/node_modules/glob": {
+ "version": "8.1.0",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/typeorm/node_modules/minimatch": {
+ "version": "5.1.6",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/typeorm/node_modules/mkdirp": {
+ "version": "2.1.6",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.1.3",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/uid": {
+ "version": "2.0.2",
+ "license": "MIT",
+ "dependencies": {
+ "@lukeed/csprng": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/untildify": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.11",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/upper-case-first": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "9.0.0",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.1.0",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/validator": {
+ "version": "13.9.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/visit-values": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "3.2.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "license": "ISC"
+ },
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.13.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
new file mode 100644
index 00000000..3148430e
--- /dev/null
+++ b/services/content-watcher/package.json
@@ -0,0 +1,86 @@
+{
+ "name": "content-publishing-service",
+ "version": "1.0.0",
+ "description": "A microservice to ContentPublishing graphs in DSNP/Frequency",
+ "main": "dist/src/main.js",
+ "scripts": {
+ "build": "npx tsc",
+ "start": "env TS_NODE_BASEURL=./dist/src node -r tsconfig-paths/register dist/src/main.js",
+ "start:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register src/main.ts",
+ "start:dev:docker": "npm ci && ts-node-dev -r tsconfig-paths/register src/main.ts",
+ "docker-build": "docker build -t content-publishing-service .",
+ "docker-build:dev": "docker-compose -f docker-compose.dev.yaml build",
+ "docker-run": "docker build -t content-publishing-service-deploy . ; docker run -p 6379:6379 --env-file .env.dev content-publishing-service-deploy",
+ "docker-run:dev": "docker-compose -f docker-compose.dev.yaml up -d ; docker-compose -f docker-compose.dev.yaml logs -f content-publishing-service",
+ "docker-stop:dev": "docker-compose -f docker-compose.dev.yaml stop",
+ "clean": "rm -Rf dist",
+ "lint": "tsc --noEmit --pretty && eslint \"**/*.ts\" --fix",
+ "pretest": "cp env.template .env",
+ "test": "jest --coverage --verbose"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/AmplicaLabs/content-publishing-service.git"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/AmplicaLabs/content-publishing-service/issues"
+ },
+ "homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
+ "dependencies": {
+ "@dsnp/graph-sdk": "^0.0.11",
+ "@frequency-chain/api-augment": "1.7.0",
+ "@liaoliaots/nestjs-redis": "^9.0.5",
+ "@nestjs/axios": "^2.0.0",
+ "@nestjs/bullmq": "^10.0.0",
+ "@nestjs/common": "^9.4.0",
+ "@nestjs/config": "^2.3.1",
+ "@nestjs/core": "^9.4.0",
+ "@nestjs/event-emitter": "^1.4.1",
+ "@nestjs/platform-express": "^9.4.0",
+ "@nestjs/schedule": "^3.0.1",
+ "@nestjs/testing": "^9.4.0",
+ "@nestjs/typeorm": "^9.0.1",
+ "@polkadot/api": "^10.9.1",
+ "@polkadot/api-base": "^10.9.1",
+ "@polkadot/keyring": "^12.3.2",
+ "@polkadot/types": "^10.9.1",
+ "@polkadot/util": "^12.3.2",
+ "@polkadot/util-crypto": "^12.3.2",
+ "axios": "^1.3.6",
+ "bullmq": "^3.0.0",
+ "class-transformer": "^0.5.1",
+ "class-validator": "^0.14.0",
+ "ioredis": "^5.3.2",
+ "joi": "^17.9.1",
+ "rxjs": "^7.8.1",
+ "time-constants": "^1.0.3"
+ },
+ "devDependencies": {
+ "@jest/globals": "^29.5.0",
+ "@polkadot/typegen": "10.9.1",
+ "@types/jest": "^29.5.2",
+ "@types/time-constants": "^1.0.0",
+ "@typescript-eslint/parser": "^5.59.8",
+ "@typescript-eslint/typescript-estree": "5.59.8",
+ "dotenv": "^16.3.1",
+ "eslint": "^8.42.0",
+ "eslint-config-airbnb-base": "^15.0.0",
+ "eslint-config-airbnb-typescript": "^17.0.0",
+ "eslint-config-prettier": "^8.8.0",
+ "eslint-import-resolver-typescript": "^3.5.5",
+ "eslint-plugin-import": "^2.27.5",
+ "eslint-plugin-n": "^15.7.0",
+ "eslint-plugin-nestjs": "^1.2.3",
+ "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-promise": "^6.1.1",
+ "license-report": "^6.4.0",
+ "ts-jest": "^29.1.0",
+ "ts-node": "^10.9.1",
+ "ts-node-dev": "^2.0.0",
+ "tsconfig-paths": "^4.2.0",
+ "typescript": "^5.1.3"
+ }
+}
diff --git a/services/content-watcher/src/blockchain/blockchain-constants.ts b/services/content-watcher/src/blockchain/blockchain-constants.ts
new file mode 100644
index 00000000..31ec1057
--- /dev/null
+++ b/services/content-watcher/src/blockchain/blockchain-constants.ts
@@ -0,0 +1,29 @@
+export namespace BlockchainConstants {
+ interface IExtrinsicCall {
+ pallet: string;
+ extrinsic: string;
+ }
+
+ interface IChainEvent {
+ eventPallet: string;
+ event: string;
+ }
+
+ interface IChainQuery {
+ queryPallet: string;
+ query: string;
+ }
+
+ interface IChainRpc {
+ rpcPallet: string;
+ rpc: string;
+ }
+
+ const PALLET_FREQ_TX_PYMT = 'frequencyTxPayment';
+ const PALLET_STATEFUL_STORAGE = 'statefulStorage';
+
+ const EX_PAY_CAPACITY_BATCH = 'payWithCapacityBatchAll';
+ const EX_UPSERT_PAGE = 'upsertPage';
+
+ const PAY_WITH_CAPACITY_BATCH: IExtrinsicCall = { pallet: PALLET_FREQ_TX_PYMT, extrinsic: EX_PAY_CAPACITY_BATCH };
+}
diff --git a/services/content-watcher/src/blockchain/blockchain.module.ts b/services/content-watcher/src/blockchain/blockchain.module.ts
new file mode 100644
index 00000000..facacf9c
--- /dev/null
+++ b/services/content-watcher/src/blockchain/blockchain.module.ts
@@ -0,0 +1,15 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { Module } from '@nestjs/common';
+import { BlockchainService } from './blockchain.service';
+import { ConfigModule } from '../config/config.module';
+
+@Module({
+ imports: [ConfigModule],
+ controllers: [],
+ providers: [BlockchainService],
+ exports: [BlockchainService],
+})
+export class BlockchainModule {}
diff --git a/services/content-watcher/src/blockchain/blockchain.service.ts b/services/content-watcher/src/blockchain/blockchain.service.ts
new file mode 100644
index 00000000..efa606a5
--- /dev/null
+++ b/services/content-watcher/src/blockchain/blockchain.service.ts
@@ -0,0 +1,138 @@
+/* eslint-disable no-underscore-dangle */
+import { ConfigService } from '#app/config/config.service';
+import { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
+import { ApiPromise, ApiRx, HttpProvider, WsProvider } from '@polkadot/api';
+import { firstValueFrom } from 'rxjs';
+import { options } from '@frequency-chain/api-augment';
+import { KeyringPair } from '@polkadot/keyring/types';
+import { BlockHash, BlockNumber } from '@polkadot/types/interfaces';
+import { SubmittableExtrinsic } from '@polkadot/api/types';
+import { AnyNumber, ISubmittableResult } from '@polkadot/types/types';
+import { u32, Option, u128 } from '@polkadot/types';
+import { PalletCapacityCapacityDetails, PalletCapacityEpochInfo } from '@polkadot/types/lookup';
+import { Extrinsic } from './extrinsic';
+
+@Injectable()
+export class BlockchainService implements OnApplicationBootstrap, OnApplicationShutdown {
+ public api: ApiRx;
+
+ public apiPromise: ApiPromise;
+
+ private configService: ConfigService;
+
+ private logger: Logger;
+
+ public async onApplicationBootstrap() {
+ const providerUrl = this.configService.frequencyUrl!;
+ let provider: any;
+ if (/^ws/.test(providerUrl.toString())) {
+ provider = new WsProvider(providerUrl.toString());
+ } else if (/^http/.test(providerUrl.toString())) {
+ provider = new HttpProvider(providerUrl.toString());
+ } else {
+ this.logger.error(`Unrecognized chain URL type: ${providerUrl.toString()}`);
+ throw new Error('Unrecognized chain URL type');
+ }
+ this.api = await firstValueFrom(ApiRx.create({ provider, ...options }));
+ this.apiPromise = await ApiPromise.create({ provider, ...options });
+ await Promise.all([firstValueFrom(this.api.isReady), this.apiPromise.isReady]);
+ this.logger.log('Blockchain API ready.');
+ }
+
+ public async onApplicationShutdown(signal?: string | undefined) {
+ const promises: Promise[] = [];
+ if (this.api) {
+ promises.push(this.api.disconnect());
+ }
+
+ if (this.apiPromise) {
+ promises.push(this.apiPromise.disconnect());
+ }
+ await Promise.all(promises);
+ }
+
+ constructor(configService: ConfigService) {
+ this.configService = configService;
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ public getBlockHash(block: BlockNumber | AnyNumber): Promise {
+ return this.apiPromise.rpc.chain.getBlockHash(block);
+ }
+
+ public async getBlockNumberForHash(hash: string): Promise {
+ const block = await this.apiPromise.rpc.chain.getBlock(hash);
+ if (block) {
+ return block.block.header.number.toNumber();
+ }
+
+ this.logger.error(`No block found corresponding to hash ${hash}`);
+ return undefined;
+ }
+
+ public createType(type: string, ...args: (any | undefined)[]) {
+ return this.api.registry.createType(type, ...args);
+ }
+
+ public createExtrinsicCall({ pallet, extrinsic }: { pallet: string; extrinsic: string }, ...args: (any | undefined)[]): SubmittableExtrinsic<'rxjs', ISubmittableResult> {
+ return this.api.tx[pallet][extrinsic](...args);
+ }
+
+ public createExtrinsic(
+ { pallet, extrinsic }: { pallet: string; extrinsic: string },
+ { eventPallet, event }: { eventPallet?: string; event?: string },
+ keys: KeyringPair,
+ ...args: (any | undefined)[]
+ ): Extrinsic {
+ const targetEvent = eventPallet && event ? this.api.events[eventPallet][event] : undefined;
+ return new Extrinsic(this.api, this.api.tx[pallet][extrinsic](...args), keys, targetEvent);
+ }
+
+ public rpc(pallet: string, rpc: string, ...args: (any | undefined)[]): Promise {
+ return this.apiPromise.rpc[pallet][rpc](...args);
+ }
+
+ public query(pallet: string, extrinsic: string, ...args: (any | undefined)[]): Promise {
+ return args ? this.apiPromise.query[pallet][extrinsic](...args) : this.apiPromise.query[pallet][extrinsic]();
+ }
+
+ public async queryAt(blockHash: BlockHash, pallet: string, extrinsic: string, ...args: (any | undefined)[]): Promise {
+ const newApi = await this.apiPromise.at(blockHash);
+ return newApi.query[pallet][extrinsic](...args);
+ }
+
+ public async capacityInfo(providerId: string): Promise<{
+ providerId: string;
+ currentBlockNumber: number;
+ nextEpochStart: number;
+ remainingCapacity: bigint;
+ totalCapacityIssued: bigint;
+ currentEpoch: bigint;
+ }> {
+ const providerU64 = this.api.createType('u64', providerId);
+ const { epochStart }: PalletCapacityEpochInfo = await this.query('capacity', 'currentEpochInfo');
+ const epochBlockLength: u32 = await this.query('capacity', 'epochLength');
+ const capacityDetailsOption: Option = await this.query('capacity', 'capacityLedger', providerU64);
+ const { remainingCapacity, totalCapacityIssued } = capacityDetailsOption.unwrapOr({ remainingCapacity: 0, totalCapacityIssued: 0 });
+ const currentBlock: u32 = await this.query('system', 'number');
+ const currentEpoch = await this.getCurrentCapacityEpoch();
+ return {
+ currentEpoch,
+ providerId,
+ currentBlockNumber: currentBlock.toNumber(),
+ nextEpochStart: epochStart.add(epochBlockLength).toNumber(),
+ remainingCapacity: typeof remainingCapacity === 'number' ? BigInt(remainingCapacity) : remainingCapacity.toBigInt(),
+ totalCapacityIssued: typeof totalCapacityIssued === 'number' ? BigInt(totalCapacityIssued) : totalCapacityIssued.toBigInt(),
+ };
+ }
+
+ public async getCurrentCapacityEpoch(): Promise {
+ const currentEpoch: u32 = await this.query('capacity', 'currentEpoch');
+ return typeof currentEpoch === 'number' ? BigInt(currentEpoch) : currentEpoch.toBigInt();
+ }
+
+ public async getCurrentEpochLength(): Promise {
+ const epochLength: u32 = await this.query('capacity', 'epochLength');
+ return typeof epochLength === 'number' ? epochLength : epochLength.toNumber();
+ }
+}
diff --git a/services/content-watcher/src/blockchain/create-keys.ts b/services/content-watcher/src/blockchain/create-keys.ts
new file mode 100644
index 00000000..b6fca978
--- /dev/null
+++ b/services/content-watcher/src/blockchain/create-keys.ts
@@ -0,0 +1,15 @@
+import { Keyring } from '@polkadot/api';
+import { KeyringPair } from '@polkadot/keyring/types';
+
+// eslint-disable-next-line import/no-mutable-exports
+export let keyring: Keyring;
+
+export function createKeys(uri: string): KeyringPair {
+ if (!keyring) {
+ keyring = new Keyring({ type: 'sr25519' });
+ }
+
+ const keys = keyring.addFromUri(uri);
+
+ return keys;
+}
diff --git a/services/content-watcher/src/blockchain/event-error.ts b/services/content-watcher/src/blockchain/event-error.ts
new file mode 100644
index 00000000..fdaedcd2
--- /dev/null
+++ b/services/content-watcher/src/blockchain/event-error.ts
@@ -0,0 +1,34 @@
+import { DispatchError } from '@polkadot/types/interfaces';
+import { SpRuntimeDispatchError } from '@polkadot/types/lookup';
+
+export class EventError extends Error {
+ name: string = '';
+
+ message: string = '';
+
+ stack?: string = '';
+
+ section?: string = '';
+
+ rawError: DispatchError | SpRuntimeDispatchError;
+
+ constructor(source: DispatchError | SpRuntimeDispatchError) {
+ super();
+
+ if (source.isModule) {
+ const decoded = source.registry.findMetaError(source.asModule);
+ this.name = decoded.name;
+ this.message = decoded.docs.join(' ');
+ this.section = decoded.section;
+ } else {
+ this.name = source.type;
+ this.message = source.type;
+ this.section = '';
+ }
+ this.rawError = source;
+ }
+
+ public toString() {
+ return `${this.section}.${this.name}: ${this.message}`;
+ }
+}
diff --git a/services/content-watcher/src/blockchain/extrinsic.ts b/services/content-watcher/src/blockchain/extrinsic.ts
new file mode 100644
index 00000000..623a84e1
--- /dev/null
+++ b/services/content-watcher/src/blockchain/extrinsic.ts
@@ -0,0 +1,116 @@
+/**
+ * These helpers return a map of events, some of which contain useful data, some of which don't.
+ * Extrinsics that "create" records typically contain an ID of the entity they created, and this
+ * would be a useful value to return. However, this data seems to be nested inside an array of arrays.
+ *
+ * Ex: schemaId = events["schemas.SchemaCreated"][]
+ *
+ * To get the value associated with an event key, we would need to query inside that nested array with
+ * a set of arbitrary indices. Should an object at any level of that querying be undefined, the helper
+ * will throw an unchecked exception.
+ *
+ * To get type checking and cast a returned event as a specific event type, you can utilize TypeScripts
+ * type guard functionality like so:
+ *
+ * const msaCreatedEvent = events.defaultEvent;
+ * if (this.api.events.msa.MsaCreated.is(msaCreatedEvent)) {
+ * msaId = msaCreatedEvent.data.msaId;
+ * }
+ *
+ * Normally, I'd say the best experience is for the helper to return both the ID of the created entity
+ * along with a map of emitted events. But in this case, returning that value will increase the complexity
+ * of each helper, since each would have to check for undefined values at every lookup. So, this may be
+ * a rare case when it is best to simply return the map of emitted events and trust the user to look them
+ * up in the test.
+ */
+
+import { ApiRx } from '@polkadot/api';
+import { SubmittableExtrinsic, ApiTypes, AugmentedEvent } from '@polkadot/api/types';
+import { Call, Event } from '@polkadot/types/interfaces';
+import { IsEvent } from '@polkadot/types/metadata/decorate/types';
+import { Codec, ISubmittableResult, AnyTuple } from '@polkadot/types/types';
+import { filter, firstValueFrom, map, pipe, tap } from 'rxjs';
+import { KeyringPair } from '@polkadot/keyring/types';
+import { ConfigService } from '#app/config/config.service';
+import { EventError } from './event-error';
+
+export type EventMap = { [key: string]: Event };
+
+function eventKey(event: Event): string {
+ return `${event.section}.${event.method}`;
+}
+
+export type ParsedEventResult = [any, EventMap];
+
+export class Extrinsic {
+ private event?: IsEvent;
+
+ private extrinsic: SubmittableExtrinsic<'rxjs', T>;
+
+ // private call: Call;
+ private keys: KeyringPair;
+
+ public api: ApiRx;
+
+ constructor(api: ApiRx, extrinsic: SubmittableExtrinsic<'rxjs', T>, keys: KeyringPair, targetEvent?: IsEvent) {
+ this.extrinsic = extrinsic;
+ this.keys = keys;
+ this.event = targetEvent;
+ this.api = api;
+ }
+
+ public get targetEvent() {
+ return this.event;
+ }
+
+ public signAndSend(nonce?: number): Promise {
+ return firstValueFrom(
+ this.extrinsic.signAndSend(this.keys, { nonce }).pipe(
+ filter(({ status }) => status.isInBlock || status.isFinalized),
+ this.parseResult(this.event),
+ ),
+ );
+ }
+
+ public getCall(): Call {
+ const call = this.api.createType('Call', this.extrinsic);
+ return call;
+ }
+
+ // eslint-disable-next-line no-shadow
+ private parseResult(targetEvent?: AugmentedEvent) {
+ return pipe(
+ tap((result: ISubmittableResult) => {
+ if (result.dispatchError) {
+ const err = new EventError(result.dispatchError);
+ throw err;
+ }
+ }),
+ map((result: ISubmittableResult) =>
+ result.events.reduce((acc, { event }) => {
+ acc[eventKey(event)] = event;
+ if (targetEvent && targetEvent.is(event)) {
+ acc.defaultEvent = event;
+ }
+ if (this.api.events.sudo.Sudid.is(event)) {
+ const { sudoResult } = event.data;
+ if (sudoResult.isErr) {
+ const err = new EventError(sudoResult.asErr);
+ throw err;
+ }
+ }
+ return acc;
+ }, {} as EventMap),
+ ),
+ map((em) => {
+ const result: ParsedEventResult = [undefined, {}];
+ if (targetEvent && targetEvent.is(em?.defaultEvent)) {
+ result[0] = em.defaultEvent;
+ }
+ result[1] = em;
+ return result;
+ }),
+ // tap((events) => console.log(events)),
+ );
+ }
+}
diff --git a/services/content-watcher/src/config/config.module.ts b/services/content-watcher/src/config/config.module.ts
new file mode 100644
index 00000000..0b28661f
--- /dev/null
+++ b/services/content-watcher/src/config/config.module.ts
@@ -0,0 +1,12 @@
+import { ConfigModule as NestConfigModule } from '@nestjs/config';
+import { Module } from '@nestjs/common';
+import { ConfigService } from './config.service';
+import { configModuleOptions } from './env.config';
+
+@Module({
+ imports: [NestConfigModule.forRoot(configModuleOptions)],
+ controllers: [],
+ providers: [ConfigService],
+ exports: [ConfigService],
+})
+export class ConfigModule {}
diff --git a/services/content-watcher/src/config/config.service.spec.ts b/services/content-watcher/src/config/config.service.spec.ts
new file mode 100644
index 00000000..0ea8709e
--- /dev/null
+++ b/services/content-watcher/src/config/config.service.spec.ts
@@ -0,0 +1,251 @@
+/* eslint-disable import/no-extraneous-dependencies */
+/*
+https://docs.nestjs.com/fundamentals/testing#unit-testing
+*/
+
+import { Test } from '@nestjs/testing';
+import { describe, it, expect, beforeAll, jest } from '@jest/globals';
+import { ConfigModule } from '@nestjs/config';
+import { ConfigService } from './config.service';
+import { configModuleOptions } from './env.config';
+
+const setupConfigService = async (envObj: any): Promise => {
+ jest.resetModules();
+ Object.keys(process.env).forEach((key) => {
+ delete process.env[key];
+ });
+ process.env = {
+ ...envObj,
+ };
+ const moduleRef = await Test.createTestingModule({
+ imports: [
+ ConfigModule.forRoot({
+ ...configModuleOptions,
+ ignoreEnvFile: true,
+ load: [() => process.env],
+ }),
+ ],
+ controllers: [],
+ providers: [ConfigService],
+ }).compile();
+
+ await ConfigModule.envVariablesLoaded;
+
+ return moduleRef.get(ConfigService);
+};
+
+describe('ContentPublishingConfigService', () => {
+ const ALL_ENV: { [key: string]: string | undefined } = {
+ REDIS_URL: undefined,
+ FREQUENCY_URL: undefined,
+ PROVIDER_ID: undefined,
+ PROVIDER_BASE_URL: undefined,
+ PROVIDER_ACCESS_TOKEN: undefined,
+ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: undefined,
+ QUEUE_HIGH_WATER: undefined,
+ PROVIDER_ACCOUNT_SEED_PHRASE: undefined,
+ WEBHOOK_FAILURE_THRESHOLD: undefined,
+ HEALTH_CHECK_SUCCESS_THRESHOLD: undefined,
+ WEBHOOK_RETRY_INTERVAL_SECONDS: undefined,
+ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: undefined,
+ HEALTH_CHECK_MAX_RETRIES: undefined,
+ CAPACITY_LIMIT: undefined,
+ };
+
+ beforeAll(() => {
+ Object.keys(ALL_ENV).forEach((key) => {
+ ALL_ENV[key] = process.env[key];
+ });
+ });
+
+ describe('invalid environment', () => {
+ it('missing redis url should fail', async () => {
+ const { REDIS_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid redis url should fail', async () => {
+ const { REDIS_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ REDIS_URL: 'invalid url', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing frequency url should fail', async () => {
+ const { FREQUENCY_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid frequency url should fail', async () => {
+ const { FREQUENCY_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ FREQUENCY_URL: 'invalid url', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing provider id should fail', async () => {
+ const { PROVIDER_ID: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid provider id should fail', async () => {
+ const { PROVIDER_ID: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ PROVIDER_ID: 'bad string', ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ PROVIDER_ID: '-1', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing provider base url should fail', async () => {
+ const { PROVIDER_BASE_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid provider base url should fail', async () => {
+ const { PROVIDER_BASE_URL: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ PROVIDER_BASE_URL: 'invalid url', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing provider access token should be ok', async () => {
+ const { PROVIDER_ACCESS_TOKEN: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ ...env })).resolves.toBeDefined();
+ });
+
+ it('empty provider access token should fail', async () => {
+ const { PROVIDER_ACCESS_TOKEN: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ PROVIDER_ACCESS_TOKEN: '', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid scan interval should fail', async () => {
+ const { BLOCKCHAIN_SCAN_INTERVAL_MINUTES: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: 0, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid queue high water should fail', async () => {
+ const { QUEUE_HIGH_WATER: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ QUEUE_HIGH_WATER: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ QUEUE_HIGH_WATER: 99, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ QUEUE_HIGH_WATER: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing provider account seed phrase should fail', async () => {
+ const { PROVIDER_ACCOUNT_SEED_PHRASE: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ PROVIDER_ACCOUNT_SEED_PHRASE: undefined, ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid provider account seed phrase should fail', async () => {
+ const { PROVIDER_ACCOUNT_SEED_PHRASE: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ PROVIDER_ACCOUNT_SEED_PHRASE: 'hello, world', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid webhook failure threshold should fail', async () => {
+ const { WEBHOOK_FAILURE_THRESHOLD: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ WEBHOOK_FAILURE_THRESHOLD: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ WEBHOOK_FAILURE_THRESHOLD: 0, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ WEBHOOK_FAILURE_THRESHOLD: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid health check success threshold should fail', async () => {
+ const { HEALTH_CHECK_SUCCESS_THRESHOLD: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ HEALTH_CHECK_SUCCESS_THRESHOLD: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ HEALTH_CHECK_SUCCESS_THRESHOLD: 0, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ HEALTH_CHECK_SUCCESS_THRESHOLD: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid webhook retry interval should fail', async () => {
+ const { WEBHOOK_RETRY_INTERVAL_SECONDS: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ WEBHOOK_RETRY_INTERVAL_SECONDS: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ WEBHOOK_RETRY_INTERVAL_SECONDS: 0, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ WEBHOOK_RETRY_INTERVAL_SECONDS: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid health check max retry interval should fail', async () => {
+ const { HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: 0, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid health check max retry interval should fail', async () => {
+ const { HEALTH_CHECK_MAX_RETRIES: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ HEALTH_CHECK_MAX_RETRIES: -1, ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ HEALTH_CHECK_MAX_RETRIES: 'foo', ...env })).rejects.toBeDefined();
+ });
+
+ it('missing capacity limits should fail', async () => {
+ const { CAPACITY_LIMIT: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ CAPACITY_LIMIT: undefined, ...env })).rejects.toBeDefined();
+ });
+
+ it('invalid capacity limit should fail', async () => {
+ const { CAPACITY_LIMIT: dummy, ...env } = ALL_ENV;
+ await expect(setupConfigService({ CAPACITY_LIMIT: '{ "type": "bad type", "value": 0 }', ...env })).rejects.toBeDefined();
+ await expect(async () => setupConfigService({ CAPACITY_LIMIT: '{ "type": "percentage", "value": -1 }', ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ CAPACITY_LIMIT: '{ "type": "percentage", "value": 101 }', ...env })).rejects.toBeDefined();
+ await expect(setupConfigService({ CAPACITY_LIMIT: '{ "type": "amount", "value": -1 }', ...env })).rejects.toBeDefined();
+ });
+ });
+
+ describe('valid environment', () => {
+ let contentPublishingConfigService: ConfigService;
+ beforeAll(async () => {
+ contentPublishingConfigService = await setupConfigService(ALL_ENV);
+ });
+
+ it('should be defined', () => {
+ expect(contentPublishingConfigService).toBeDefined();
+ });
+
+ it('should get redis url', () => {
+ expect(contentPublishingConfigService.redisUrl?.toString()).toStrictEqual(ALL_ENV.REDIS_URL?.toString());
+ });
+
+ it('should get frequency url', () => {
+ expect(contentPublishingConfigService.frequencyUrl?.toString()).toStrictEqual(ALL_ENV.FREQUENCY_URL?.toString());
+ });
+
+ it('should get provider base url', () => {
+ expect(contentPublishingConfigService.providerBaseUrl.toString()).toStrictEqual(ALL_ENV.PROVIDER_BASE_URL);
+ });
+
+ it('should get provider api token', () => {
+ expect(contentPublishingConfigService.providerApiToken!.toString()).toStrictEqual(ALL_ENV.PROVIDER_ACCESS_TOKEN);
+ });
+
+ it('should get scan interval', () => {
+ expect(contentPublishingConfigService.getBlockchainScanIntervalMinutes()).toStrictEqual(parseInt(ALL_ENV.BLOCKCHAIN_SCAN_INTERVAL_MINUTES as string, 10));
+ });
+
+ it('should get queue high water mark', () => {
+ expect(contentPublishingConfigService.getQueueHighWater()).toStrictEqual(parseInt(ALL_ENV.QUEUE_HIGH_WATER as string, 10));
+ });
+
+ it('should get webhook failure threshold', () => {
+ expect(contentPublishingConfigService.getWebhookFailureThreshold()).toStrictEqual(parseInt(ALL_ENV.WEBHOOK_FAILURE_THRESHOLD as string, 10));
+ });
+
+ it('should get health check success threshold', () => {
+ expect(contentPublishingConfigService.getHealthCheckSuccessThreshold()).toStrictEqual(parseInt(ALL_ENV.HEALTH_CHECK_SUCCESS_THRESHOLD as string, 10));
+ });
+
+ it('should get webhook retry interval', () => {
+ expect(contentPublishingConfigService.getWebhookRetryIntervalSeconds()).toStrictEqual(parseInt(ALL_ENV.WEBHOOK_RETRY_INTERVAL_SECONDS as string, 10));
+ });
+
+ it('should get health check max retry interval', () => {
+ expect(contentPublishingConfigService.getHealthCheckMaxRetryIntervalSeconds()).toStrictEqual(parseInt(ALL_ENV.HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS as string, 10));
+ });
+
+ it('should get health check max retries', () => {
+ expect(contentPublishingConfigService.getHealthCheckMaxRetries()).toStrictEqual(parseInt(ALL_ENV.HEALTH_CHECK_MAX_RETRIES as string, 10));
+ });
+
+ it('should get provider id', () => {
+ expect(contentPublishingConfigService.getProviderId()).toStrictEqual(ALL_ENV.PROVIDER_ID as string);
+ });
+
+ it('should get provider seed phrase', () => {
+ expect(contentPublishingConfigService.getProviderAccountSeedPhrase()).toStrictEqual(ALL_ENV.PROVIDER_ACCOUNT_SEED_PHRASE);
+ });
+
+ it('should get capacity limit', () => {
+ expect(contentPublishingConfigService.getCapacityLimit()).toStrictEqual(JSON.parse(ALL_ENV.CAPACITY_LIMIT!));
+ });
+ });
+});
diff --git a/services/content-watcher/src/config/config.service.ts b/services/content-watcher/src/config/config.service.ts
new file mode 100644
index 00000000..9fd6cbdb
--- /dev/null
+++ b/services/content-watcher/src/config/config.service.ts
@@ -0,0 +1,91 @@
+/*
+https://docs.nestjs.com/providers#services
+*/
+
+import { ICapacityLimit } from '#app/interfaces/capacity-limit.interface';
+import type { EnvironmentType } from '@dsnp/graph-sdk';
+import { Injectable } from '@nestjs/common';
+import { ConfigService as NestConfigService } from '@nestjs/config';
+
+export interface ConfigEnvironmentVariables {
+ REDIS_URL: URL;
+ FREQUENCY_URL: URL;
+ PROVIDER_ID: string;
+ PROVIDER_BASE_URL: URL;
+ PROVIDER_ACCESS_TOKEN: string;
+ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: number;
+ QUEUE_HIGH_WATER: number;
+ WEBHOOK_FAILURE_THRESHOLD: number;
+ HEALTH_CHECK_SUCCESS_THRESHOLD: number;
+ WEBHOOK_RETRY_INTERVAL_SECONDS: number;
+ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: number;
+ HEALTH_CHECK_MAX_RETRIES: number;
+ PROVIDER_ACCOUNT_SEED_PHRASE: string;
+ CAPACITY_LIMIT: ICapacityLimit;
+}
+
+/// Config service to get global app and provider-specific config values.
+@Injectable()
+export class ConfigService {
+ private capacityLimit: ICapacityLimit;
+
+ constructor(private nestConfigService: NestConfigService) {
+ this.capacityLimit = JSON.parse(nestConfigService.get('CAPACITY_LIMIT')!);
+ }
+
+ public get redisUrl(): URL {
+ return this.nestConfigService.get('REDIS_URL')!;
+ }
+
+ public get frequencyUrl(): URL {
+ return this.nestConfigService.get('FREQUENCY_URL')!;
+ }
+
+ public get providerBaseUrl(): URL {
+ return this.nestConfigService.get('PROVIDER_BASE_URL')!;
+ }
+
+ public get providerApiToken(): string | undefined {
+ return this.nestConfigService.get('PROVIDER_ACCESS_TOKEN');
+ }
+
+ public getBlockchainScanIntervalMinutes(): number {
+ return this.nestConfigService.get('BLOCKCHAIN_SCAN_INTERVAL_MINUTES') ?? 1;
+ }
+
+ public getQueueHighWater(): number {
+ return this.nestConfigService.get('QUEUE_HIGH_WATER')!;
+ }
+
+ public getWebhookFailureThreshold(): number {
+ return this.nestConfigService.get('WEBHOOK_FAILURE_THRESHOLD')!;
+ }
+
+ public getHealthCheckSuccessThreshold(): number {
+ return this.nestConfigService.get('HEALTH_CHECK_SUCCESS_THRESHOLD')!;
+ }
+
+ public getWebhookRetryIntervalSeconds(): number {
+ return this.nestConfigService.get('WEBHOOK_RETRY_INTERVAL_SECONDS')!;
+ }
+
+ public getHealthCheckMaxRetryIntervalSeconds(): number {
+ return this.nestConfigService.get('HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS')!;
+ }
+
+ public getHealthCheckMaxRetries(): number {
+ return this.nestConfigService.get('HEALTH_CHECK_MAX_RETRIES')!;
+ }
+
+ public getProviderId(): string {
+ return this.nestConfigService.get('PROVIDER_ID')!;
+ }
+
+ public getProviderAccountSeedPhrase(): string {
+ return this.nestConfigService.get('PROVIDER_ACCOUNT_SEED_PHRASE')!;
+ }
+
+ public getCapacityLimit(): ICapacityLimit {
+ return this.capacityLimit;
+ }
+}
diff --git a/services/content-watcher/src/config/env.config.ts b/services/content-watcher/src/config/env.config.ts
new file mode 100644
index 00000000..ea6f75ec
--- /dev/null
+++ b/services/content-watcher/src/config/env.config.ts
@@ -0,0 +1,64 @@
+import Joi from 'joi';
+import { ConfigModuleOptions } from '@nestjs/config';
+import { mnemonicValidate } from '@polkadot/util-crypto';
+
+export const configModuleOptions: ConfigModuleOptions = {
+ isGlobal: true,
+ validationSchema: Joi.object({
+ REDIS_URL: Joi.string().uri().required(),
+ FREQUENCY_URL: Joi.string().uri().required(),
+ PROVIDER_ID: Joi.required().custom((value: string, helpers) => {
+ try {
+ const id = BigInt(value);
+ if (id < 0) {
+ throw new Error('Provider ID must be > 0');
+ }
+ } catch (e) {
+ return helpers.error('any.invalid');
+ }
+ return value;
+ }),
+ PROVIDER_BASE_URL: Joi.string().uri().required(),
+ PROVIDER_ACCESS_TOKEN: Joi.string(),
+ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: Joi.number()
+ .min(1)
+ .default(3 * 60),
+ QUEUE_HIGH_WATER: Joi.number().min(100).default(1000),
+ PROVIDER_ACCOUNT_SEED_PHRASE: Joi.string()
+ .required()
+ .custom((value: string, helpers) => {
+ if (!mnemonicValidate(value)) {
+ return helpers.error('any.invalid');
+ }
+ return value;
+ }),
+ WEBHOOK_FAILURE_THRESHOLD: Joi.number().min(1).default(3),
+ WEBHOOK_RETRY_INTERVAL_SECONDS: Joi.number().min(1).default(10),
+ HEALTH_CHECK_SUCCESS_THRESHOLD: Joi.number().min(1).default(10),
+ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: Joi.number().min(1).default(64),
+ HEALTH_CHECK_MAX_RETRIES: Joi.number().min(0).default(20),
+ CAPACITY_LIMIT: Joi.string()
+ .custom((value: string, helpers) => {
+ try {
+ const obj = JSON.parse(value);
+ const schema = Joi.object({
+ type: Joi.string()
+ .required()
+ .pattern(/^(percentage|amount)$/),
+ value: Joi.alternatives()
+ .conditional('type', { is: 'percentage', then: Joi.number().min(0).max(100), otherwise: Joi.number().min(0) })
+ .required(),
+ });
+ const result = schema.validate(obj);
+ if (result.error) {
+ return helpers.error('any.invalid');
+ }
+ } catch (e) {
+ return helpers.error('any.invalid');
+ }
+
+ return value;
+ })
+ .required(),
+ }),
+};
diff --git a/services/content-watcher/src/content-publishing-service.controller.ts b/services/content-watcher/src/content-publishing-service.controller.ts
new file mode 100644
index 00000000..4053c001
--- /dev/null
+++ b/services/content-watcher/src/content-publishing-service.controller.ts
@@ -0,0 +1,18 @@
+import { Controller, Get, HttpStatus, Logger } from '@nestjs/common';
+
+@Controller('content-publishing-service')
+export class ContentPublishingServiceController {
+ private readonly logger: Logger;
+
+ constructor() {
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @Get('health')
+ health() {
+ return {
+ status: HttpStatus.OK,
+ };
+ }
+}
diff --git a/services/content-watcher/src/content-publishing-service.module.ts b/services/content-watcher/src/content-publishing-service.module.ts
new file mode 100644
index 00000000..aa13ff72
--- /dev/null
+++ b/services/content-watcher/src/content-publishing-service.module.ts
@@ -0,0 +1,51 @@
+import { Module } from '@nestjs/common';
+import { EventEmitterModule } from '@nestjs/event-emitter';
+import { BullModule } from '@nestjs/bullmq';
+import { ScheduleModule } from '@nestjs/schedule';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { ContentPublishingServiceController } from './content-publishing-service.controller';
+import { ConfigService } from './config/config.service';
+import { ConfigModule } from './config/config.module';
+import { DevelopmentController } from './development.controller';
+import { BlockchainModule } from './blockchain/blockchain.module';
+
+@Module({
+ imports: [
+ BullModule,
+ ConfigModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ EventEmitterModule.forRoot({
+ // Use this instance throughout the application
+ global: true,
+ // set this to `true` to use wildcards
+ wildcard: false,
+ // the delimiter used to segment namespaces
+ delimiter: '.',
+ // set this to `true` if you want to emit the newListener event
+ newListener: false,
+ // set this to `true` if you want to emit the removeListener event
+ removeListener: false,
+ // the maximum amount of listeners that can be assigned to an event
+ maxListeners: 10,
+ // show event name in memory leak message when more than maximum amount of listeners is assigned
+ verboseMemoryLeak: false,
+ // disable throwing uncaughtException if an error event is emitted and it has no listeners
+ ignoreErrors: false,
+ }),
+ ScheduleModule.forRoot(),
+ BlockchainModule,
+ ],
+ providers: [ConfigService],
+ controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ContentPublishingServiceController] : [ContentPublishingServiceController],
+ exports: [],
+})
+export class ContentPublishingServiceModule {}
diff --git a/services/content-watcher/src/development.controller.ts b/services/content-watcher/src/development.controller.ts
new file mode 100644
index 00000000..1c5812f8
--- /dev/null
+++ b/services/content-watcher/src/development.controller.ts
@@ -0,0 +1,21 @@
+/*
+This is a controller providing some endpoints useful for development and testing.
+To use it, simply rename and remove the '.dev' extension
+*/
+
+// eslint-disable-next-line max-classes-per-file
+import { Controller, Logger, Post, Body, Param, Query, HttpException, HttpStatus } from '@nestjs/common';
+import { InjectQueue } from '@nestjs/bullmq';
+import { Queue } from 'bullmq';
+import { plainToClass } from 'class-transformer';
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import Redis from 'ioredis';
+
+@Controller('content-publishing-service/dev')
+export class DevelopmentController {
+ private readonly logger: Logger;
+
+ constructor() {
+ this.logger = new Logger(this.constructor.name);
+ }
+}
diff --git a/services/content-watcher/src/interfaces/capacity-limit.interface.ts b/services/content-watcher/src/interfaces/capacity-limit.interface.ts
new file mode 100644
index 00000000..d2b1d858
--- /dev/null
+++ b/services/content-watcher/src/interfaces/capacity-limit.interface.ts
@@ -0,0 +1,4 @@
+export interface ICapacityLimit {
+ type: 'percentage' | 'amount';
+ value: number;
+}
diff --git a/services/content-watcher/src/main.ts b/services/content-watcher/src/main.ts
new file mode 100644
index 00000000..05fafc2d
--- /dev/null
+++ b/services/content-watcher/src/main.ts
@@ -0,0 +1,38 @@
+import { NestFactory } from '@nestjs/core';
+import { Logger, ValidationPipe } from '@nestjs/common';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { ContentPublishingServiceModule } from './content-publishing-service.module';
+
+const logger = new Logger('main');
+
+// Monkey-patch BigInt so that JSON.stringify will work
+// eslint-disable-next-line
+BigInt.prototype['toJSON'] = function () { return this.toString() };
+
+async function bootstrap() {
+ const app = await NestFactory.create(ContentPublishingServiceModule, {
+ logger: process.env.DEBUG ? ['error', 'warn', 'log', 'verbose', 'debug'] : ['error', 'warn', 'log'],
+ });
+
+ // Get event emitter & register a shutdown listener
+ const eventEmitter = app.get(EventEmitter2);
+ eventEmitter.on('shutdown', async () => {
+ logger.warn('Received shutdown event');
+ await app.close();
+ });
+
+ try {
+ app.enableShutdownHooks();
+ app.useGlobalPipes(new ValidationPipe());
+ await app.listen(3000);
+ } catch (e) {
+ await app.close();
+ logger.log('****** MAIN CATCH ********');
+ logger.error(e);
+ if (e instanceof Error) {
+ logger.error(e.stack);
+ }
+ }
+}
+
+bootstrap();
diff --git a/services/content-watcher/tsconfig.json b/services/content-watcher/tsconfig.json
new file mode 100644
index 00000000..5a2efd47
--- /dev/null
+++ b/services/content-watcher/tsconfig.json
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Base",
+ "compilerOptions": {
+ "allowSyntheticDefaultImports": true,
+ "baseUrl": "./src",
+ "esModuleInterop": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "module": "CommonJS",
+ "moduleResolution": "node",
+ "noImplicitAny": false,
+ "noImplicitThis": false,
+ "outDir": "dist",
+ "paths": {
+ "#app/*": [
+ "*"
+ ]
+ },
+ "resolveJsonModule": true,
+ "sourceMap": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "strictPropertyInitialization": false,
+ "target": "es2022",
+ "typeRoots": [
+ "node_modules/@types"
+ ]
+ },
+ "include": [
+ "./**/*.ts"
+ ],
+ "exclude": [
+ "node_modules/**",
+ "./dist/**",
+ "/tools/**"
+ ]
+}
From 007ac628434dc93e35f6a53c3e58b2ea3733d95b Mon Sep 17 00:00:00 2001
From: Aramik
Date: Wed, 23 Aug 2023 10:09:13 -0700
Subject: [PATCH 003/137] init monorepo for nestjs (#8)
---
services/content-watcher/.gitignore | 1 +
services/content-watcher/INSTALLING.md | 6 --
.../api/src/api.controller.ts} | 4 +-
.../api/src/api.module.ts} | 6 +-
.../src/blockchain/blockchain-constants.ts | 0
.../api}/src/blockchain/blockchain.module.ts | 0
.../api}/src/blockchain/blockchain.service.ts | 2 +-
.../api}/src/blockchain/create-keys.ts | 0
.../api}/src/blockchain/event-error.ts | 0
.../api}/src/blockchain/extrinsic.ts | 2 +-
.../api}/src/config/config.module.ts | 0
.../api}/src/config/config.service.spec.ts | 30 --------
.../api}/src/config/config.service.ts | 13 +---
.../{ => apps/api}/src/config/env.config.ts | 2 -
.../api}/src/development.controller.ts | 2 +-
.../interfaces/capacity-limit.interface.ts | 0
.../{ => apps/api}/src/main.ts | 4 +-
.../apps/api/tsconfig.app.json | 9 +++
.../apps/worker/src/consumer.ts | 18 +++++
.../apps/worker/src/event.listener.ts | 19 +++++
.../content-watcher/apps/worker/src/main.ts | 10 +++
.../apps/worker/src/worker.module.ts | 22 ++++++
.../apps/worker/src/worker.service.ts | 9 +++
.../apps/worker/tsconfig.app.json | 9 +++
services/content-watcher/env.template | 4 -
.../content-watcher/libs/common/src/index.ts | 8 ++
.../libs/common/tsconfig.lib.json | 9 +++
services/content-watcher/nest-cli.json | 37 +++++++++
services/content-watcher/package-lock.json | 18 ++---
services/content-watcher/package.json | 13 ++--
services/content-watcher/tsconfig.json | 76 ++++++++++---------
31 files changed, 214 insertions(+), 119 deletions(-)
rename services/content-watcher/{src/content-publishing-service.controller.ts => apps/api/src/api.controller.ts} (77%)
rename services/content-watcher/{src/content-publishing-service.module.ts => apps/api/src/api.module.ts} (88%)
rename services/content-watcher/{ => apps/api}/src/blockchain/blockchain-constants.ts (100%)
rename services/content-watcher/{ => apps/api}/src/blockchain/blockchain.module.ts (100%)
rename services/content-watcher/{ => apps/api}/src/blockchain/blockchain.service.ts (98%)
rename services/content-watcher/{ => apps/api}/src/blockchain/create-keys.ts (100%)
rename services/content-watcher/{ => apps/api}/src/blockchain/event-error.ts (100%)
rename services/content-watcher/{ => apps/api}/src/blockchain/extrinsic.ts (98%)
rename services/content-watcher/{ => apps/api}/src/config/config.module.ts (100%)
rename services/content-watcher/{ => apps/api}/src/config/config.service.spec.ts (88%)
rename services/content-watcher/{ => apps/api}/src/config/config.service.ts (84%)
rename services/content-watcher/{ => apps/api}/src/config/env.config.ts (95%)
rename services/content-watcher/{ => apps/api}/src/development.controller.ts (93%)
rename services/content-watcher/{ => apps/api}/src/interfaces/capacity-limit.interface.ts (100%)
rename services/content-watcher/{ => apps/api}/src/main.ts (86%)
create mode 100644 services/content-watcher/apps/api/tsconfig.app.json
create mode 100644 services/content-watcher/apps/worker/src/consumer.ts
create mode 100644 services/content-watcher/apps/worker/src/event.listener.ts
create mode 100644 services/content-watcher/apps/worker/src/main.ts
create mode 100644 services/content-watcher/apps/worker/src/worker.module.ts
create mode 100644 services/content-watcher/apps/worker/src/worker.service.ts
create mode 100644 services/content-watcher/apps/worker/tsconfig.app.json
create mode 100644 services/content-watcher/libs/common/src/index.ts
create mode 100644 services/content-watcher/libs/common/tsconfig.lib.json
create mode 100644 services/content-watcher/nest-cli.json
diff --git a/services/content-watcher/.gitignore b/services/content-watcher/.gitignore
index b1b73f10..3ad330f8 100644
--- a/services/content-watcher/.gitignore
+++ b/services/content-watcher/.gitignore
@@ -3,3 +3,4 @@ dist
.env*
.vscode
coverage
+.idea
\ No newline at end of file
diff --git a/services/content-watcher/INSTALLING.md b/services/content-watcher/INSTALLING.md
index 4112867f..4eaa5041 100644
--- a/services/content-watcher/INSTALLING.md
+++ b/services/content-watcher/INSTALLING.md
@@ -40,8 +40,6 @@ You must also minimally map `appendonlydir` (or the entire `dir`) to a persisten
If you choose to build & deploy the application yourself, simply install the prerequisites:
* NodeJS 18
-Note that, at present, due to limitaions in the `@dsnp/graph-sdk` module, the applcation can only be run on a `linux/amd64` platform. Support for other platforms is contingent on building & installing the `@dsnp/graph-sdk` module from source, which is outside the scope of this document.
-
To build the application:
```
npm run build
@@ -62,11 +60,7 @@ The following is a list of environment variables that may be set to control the
|-|-|-|-|
|`FREQUENCY_URL`|**yes**|Blockchain URL|_none_|
|`PROVIDER_ID`|**yes**|MSA ID of provider|_none_|
-|`PROVIDER_BASE_URL`|**yes**|URL of provider graph query endpoint|_none_|
-|`PROVIDER_ACCESS_TOKEN`|no|Optional access token to be used with requests to provider graph query endpoint|_none_|
|`PROVIDER_ACCOUNT_SEED_PHRASE`|**yes**|Seed phrase for provider control keypair|_none_|
|`REDIS_URL`|**yes**|URL used to connect to Redis instance|_none_
\*preset to the internal Redis URL in the standalone container|
|`BLOCKCHAIN_SCAN_INTERVAL_MINUTES`|no|# of minutes to wait in between scans of the blockchain|180|
|`QUEUE_HIGH_WATER`|no|# of pending graph scan queue entries to allow before pausing blockchain scanning until the next scan cycle|1000|
-|`GRAPH_ENVIRONMENT_TYPE`|**yes**|Indicates which blockchain network to connect to.
Possible values:
* `Mainnet`
* `Rococo`
* `Dev`|_none_|
-|`GRAPH_ENVIRONMENT_DEV_CONFIG`|no
*required for 'Dev' Graph Environment|JSON configuration object for GraphSDK configuration. Used to test against a local development Frequency node|_none_|
diff --git a/services/content-watcher/src/content-publishing-service.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
similarity index 77%
rename from services/content-watcher/src/content-publishing-service.controller.ts
rename to services/content-watcher/apps/api/src/api.controller.ts
index 4053c001..8221f0a1 100644
--- a/services/content-watcher/src/content-publishing-service.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -1,7 +1,7 @@
import { Controller, Get, HttpStatus, Logger } from '@nestjs/common';
-@Controller('content-publishing-service')
-export class ContentPublishingServiceController {
+@Controller('api')
+export class ApiController {
private readonly logger: Logger;
constructor() {
diff --git a/services/content-watcher/src/content-publishing-service.module.ts b/services/content-watcher/apps/api/src/api.module.ts
similarity index 88%
rename from services/content-watcher/src/content-publishing-service.module.ts
rename to services/content-watcher/apps/api/src/api.module.ts
index aa13ff72..d7da5930 100644
--- a/services/content-watcher/src/content-publishing-service.module.ts
+++ b/services/content-watcher/apps/api/src/api.module.ts
@@ -3,7 +3,7 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
import { BullModule } from '@nestjs/bullmq';
import { ScheduleModule } from '@nestjs/schedule';
import { RedisModule } from '@liaoliaots/nestjs-redis';
-import { ContentPublishingServiceController } from './content-publishing-service.controller';
+import { ApiController } from './api.controller';
import { ConfigService } from './config/config.service';
import { ConfigModule } from './config/config.module';
import { DevelopmentController } from './development.controller';
@@ -45,7 +45,7 @@ import { BlockchainModule } from './blockchain/blockchain.module';
BlockchainModule,
],
providers: [ConfigService],
- controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ContentPublishingServiceController] : [ContentPublishingServiceController],
+ controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ApiController] : [ApiController],
exports: [],
})
-export class ContentPublishingServiceModule {}
+export class ApiModule {}
diff --git a/services/content-watcher/src/blockchain/blockchain-constants.ts b/services/content-watcher/apps/api/src/blockchain/blockchain-constants.ts
similarity index 100%
rename from services/content-watcher/src/blockchain/blockchain-constants.ts
rename to services/content-watcher/apps/api/src/blockchain/blockchain-constants.ts
diff --git a/services/content-watcher/src/blockchain/blockchain.module.ts b/services/content-watcher/apps/api/src/blockchain/blockchain.module.ts
similarity index 100%
rename from services/content-watcher/src/blockchain/blockchain.module.ts
rename to services/content-watcher/apps/api/src/blockchain/blockchain.module.ts
diff --git a/services/content-watcher/src/blockchain/blockchain.service.ts b/services/content-watcher/apps/api/src/blockchain/blockchain.service.ts
similarity index 98%
rename from services/content-watcher/src/blockchain/blockchain.service.ts
rename to services/content-watcher/apps/api/src/blockchain/blockchain.service.ts
index efa606a5..fae47d1c 100644
--- a/services/content-watcher/src/blockchain/blockchain.service.ts
+++ b/services/content-watcher/apps/api/src/blockchain/blockchain.service.ts
@@ -1,5 +1,4 @@
/* eslint-disable no-underscore-dangle */
-import { ConfigService } from '#app/config/config.service';
import { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common';
import { ApiPromise, ApiRx, HttpProvider, WsProvider } from '@polkadot/api';
import { firstValueFrom } from 'rxjs';
@@ -10,6 +9,7 @@ import { SubmittableExtrinsic } from '@polkadot/api/types';
import { AnyNumber, ISubmittableResult } from '@polkadot/types/types';
import { u32, Option, u128 } from '@polkadot/types';
import { PalletCapacityCapacityDetails, PalletCapacityEpochInfo } from '@polkadot/types/lookup';
+import { ConfigService } from '../config/config.service';
import { Extrinsic } from './extrinsic';
@Injectable()
diff --git a/services/content-watcher/src/blockchain/create-keys.ts b/services/content-watcher/apps/api/src/blockchain/create-keys.ts
similarity index 100%
rename from services/content-watcher/src/blockchain/create-keys.ts
rename to services/content-watcher/apps/api/src/blockchain/create-keys.ts
diff --git a/services/content-watcher/src/blockchain/event-error.ts b/services/content-watcher/apps/api/src/blockchain/event-error.ts
similarity index 100%
rename from services/content-watcher/src/blockchain/event-error.ts
rename to services/content-watcher/apps/api/src/blockchain/event-error.ts
diff --git a/services/content-watcher/src/blockchain/extrinsic.ts b/services/content-watcher/apps/api/src/blockchain/extrinsic.ts
similarity index 98%
rename from services/content-watcher/src/blockchain/extrinsic.ts
rename to services/content-watcher/apps/api/src/blockchain/extrinsic.ts
index 623a84e1..cf704912 100644
--- a/services/content-watcher/src/blockchain/extrinsic.ts
+++ b/services/content-watcher/apps/api/src/blockchain/extrinsic.ts
@@ -31,7 +31,7 @@ import { IsEvent } from '@polkadot/types/metadata/decorate/types';
import { Codec, ISubmittableResult, AnyTuple } from '@polkadot/types/types';
import { filter, firstValueFrom, map, pipe, tap } from 'rxjs';
import { KeyringPair } from '@polkadot/keyring/types';
-import { ConfigService } from '#app/config/config.service';
+import { ConfigService } from '../config/config.service';
import { EventError } from './event-error';
export type EventMap = { [key: string]: Event };
diff --git a/services/content-watcher/src/config/config.module.ts b/services/content-watcher/apps/api/src/config/config.module.ts
similarity index 100%
rename from services/content-watcher/src/config/config.module.ts
rename to services/content-watcher/apps/api/src/config/config.module.ts
diff --git a/services/content-watcher/src/config/config.service.spec.ts b/services/content-watcher/apps/api/src/config/config.service.spec.ts
similarity index 88%
rename from services/content-watcher/src/config/config.service.spec.ts
rename to services/content-watcher/apps/api/src/config/config.service.spec.ts
index 0ea8709e..52bdd194 100644
--- a/services/content-watcher/src/config/config.service.spec.ts
+++ b/services/content-watcher/apps/api/src/config/config.service.spec.ts
@@ -39,8 +39,6 @@ describe('ContentPublishingConfigService', () => {
REDIS_URL: undefined,
FREQUENCY_URL: undefined,
PROVIDER_ID: undefined,
- PROVIDER_BASE_URL: undefined,
- PROVIDER_ACCESS_TOKEN: undefined,
BLOCKCHAIN_SCAN_INTERVAL_MINUTES: undefined,
QUEUE_HIGH_WATER: undefined,
PROVIDER_ACCOUNT_SEED_PHRASE: undefined,
@@ -90,26 +88,6 @@ describe('ContentPublishingConfigService', () => {
await expect(setupConfigService({ PROVIDER_ID: '-1', ...env })).rejects.toBeDefined();
});
- it('missing provider base url should fail', async () => {
- const { PROVIDER_BASE_URL: dummy, ...env } = ALL_ENV;
- await expect(setupConfigService({ ...env })).rejects.toBeDefined();
- });
-
- it('invalid provider base url should fail', async () => {
- const { PROVIDER_BASE_URL: dummy, ...env } = ALL_ENV;
- await expect(setupConfigService({ PROVIDER_BASE_URL: 'invalid url', ...env })).rejects.toBeDefined();
- });
-
- it('missing provider access token should be ok', async () => {
- const { PROVIDER_ACCESS_TOKEN: dummy, ...env } = ALL_ENV;
- await expect(setupConfigService({ ...env })).resolves.toBeDefined();
- });
-
- it('empty provider access token should fail', async () => {
- const { PROVIDER_ACCESS_TOKEN: dummy, ...env } = ALL_ENV;
- await expect(setupConfigService({ PROVIDER_ACCESS_TOKEN: '', ...env })).rejects.toBeDefined();
- });
-
it('invalid scan interval should fail', async () => {
const { BLOCKCHAIN_SCAN_INTERVAL_MINUTES: dummy, ...env } = ALL_ENV;
await expect(setupConfigService({ BLOCKCHAIN_SCAN_INTERVAL_MINUTES: -1, ...env })).rejects.toBeDefined();
@@ -200,14 +178,6 @@ describe('ContentPublishingConfigService', () => {
expect(contentPublishingConfigService.frequencyUrl?.toString()).toStrictEqual(ALL_ENV.FREQUENCY_URL?.toString());
});
- it('should get provider base url', () => {
- expect(contentPublishingConfigService.providerBaseUrl.toString()).toStrictEqual(ALL_ENV.PROVIDER_BASE_URL);
- });
-
- it('should get provider api token', () => {
- expect(contentPublishingConfigService.providerApiToken!.toString()).toStrictEqual(ALL_ENV.PROVIDER_ACCESS_TOKEN);
- });
-
it('should get scan interval', () => {
expect(contentPublishingConfigService.getBlockchainScanIntervalMinutes()).toStrictEqual(parseInt(ALL_ENV.BLOCKCHAIN_SCAN_INTERVAL_MINUTES as string, 10));
});
diff --git a/services/content-watcher/src/config/config.service.ts b/services/content-watcher/apps/api/src/config/config.service.ts
similarity index 84%
rename from services/content-watcher/src/config/config.service.ts
rename to services/content-watcher/apps/api/src/config/config.service.ts
index 9fd6cbdb..ff789c50 100644
--- a/services/content-watcher/src/config/config.service.ts
+++ b/services/content-watcher/apps/api/src/config/config.service.ts
@@ -2,17 +2,14 @@
https://docs.nestjs.com/providers#services
*/
-import { ICapacityLimit } from '#app/interfaces/capacity-limit.interface';
-import type { EnvironmentType } from '@dsnp/graph-sdk';
import { Injectable } from '@nestjs/common';
import { ConfigService as NestConfigService } from '@nestjs/config';
+import { ICapacityLimit } from '../interfaces/capacity-limit.interface';
export interface ConfigEnvironmentVariables {
REDIS_URL: URL;
FREQUENCY_URL: URL;
PROVIDER_ID: string;
- PROVIDER_BASE_URL: URL;
- PROVIDER_ACCESS_TOKEN: string;
BLOCKCHAIN_SCAN_INTERVAL_MINUTES: number;
QUEUE_HIGH_WATER: number;
WEBHOOK_FAILURE_THRESHOLD: number;
@@ -41,14 +38,6 @@ export class ConfigService {
return this.nestConfigService.get('FREQUENCY_URL')!;
}
- public get providerBaseUrl(): URL {
- return this.nestConfigService.get('PROVIDER_BASE_URL')!;
- }
-
- public get providerApiToken(): string | undefined {
- return this.nestConfigService.get('PROVIDER_ACCESS_TOKEN');
- }
-
public getBlockchainScanIntervalMinutes(): number {
return this.nestConfigService.get('BLOCKCHAIN_SCAN_INTERVAL_MINUTES') ?? 1;
}
diff --git a/services/content-watcher/src/config/env.config.ts b/services/content-watcher/apps/api/src/config/env.config.ts
similarity index 95%
rename from services/content-watcher/src/config/env.config.ts
rename to services/content-watcher/apps/api/src/config/env.config.ts
index ea6f75ec..8e83ddf8 100644
--- a/services/content-watcher/src/config/env.config.ts
+++ b/services/content-watcher/apps/api/src/config/env.config.ts
@@ -18,8 +18,6 @@ export const configModuleOptions: ConfigModuleOptions = {
}
return value;
}),
- PROVIDER_BASE_URL: Joi.string().uri().required(),
- PROVIDER_ACCESS_TOKEN: Joi.string(),
BLOCKCHAIN_SCAN_INTERVAL_MINUTES: Joi.number()
.min(1)
.default(3 * 60),
diff --git a/services/content-watcher/src/development.controller.ts b/services/content-watcher/apps/api/src/development.controller.ts
similarity index 93%
rename from services/content-watcher/src/development.controller.ts
rename to services/content-watcher/apps/api/src/development.controller.ts
index 1c5812f8..5aed5f47 100644
--- a/services/content-watcher/src/development.controller.ts
+++ b/services/content-watcher/apps/api/src/development.controller.ts
@@ -11,7 +11,7 @@ import { plainToClass } from 'class-transformer';
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import Redis from 'ioredis';
-@Controller('content-publishing-service/dev')
+@Controller('api/dev')
export class DevelopmentController {
private readonly logger: Logger;
diff --git a/services/content-watcher/src/interfaces/capacity-limit.interface.ts b/services/content-watcher/apps/api/src/interfaces/capacity-limit.interface.ts
similarity index 100%
rename from services/content-watcher/src/interfaces/capacity-limit.interface.ts
rename to services/content-watcher/apps/api/src/interfaces/capacity-limit.interface.ts
diff --git a/services/content-watcher/src/main.ts b/services/content-watcher/apps/api/src/main.ts
similarity index 86%
rename from services/content-watcher/src/main.ts
rename to services/content-watcher/apps/api/src/main.ts
index 05fafc2d..cf1ce08c 100644
--- a/services/content-watcher/src/main.ts
+++ b/services/content-watcher/apps/api/src/main.ts
@@ -1,7 +1,7 @@
import { NestFactory } from '@nestjs/core';
import { Logger, ValidationPipe } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
-import { ContentPublishingServiceModule } from './content-publishing-service.module';
+import { ApiModule } from './api.module';
const logger = new Logger('main');
@@ -10,7 +10,7 @@ const logger = new Logger('main');
BigInt.prototype['toJSON'] = function () { return this.toString() };
async function bootstrap() {
- const app = await NestFactory.create(ContentPublishingServiceModule, {
+ const app = await NestFactory.create(ApiModule, {
logger: process.env.DEBUG ? ['error', 'warn', 'log', 'verbose', 'debug'] : ['error', 'warn', 'log'],
});
diff --git a/services/content-watcher/apps/api/tsconfig.app.json b/services/content-watcher/apps/api/tsconfig.app.json
new file mode 100644
index 00000000..e2e0b2ff
--- /dev/null
+++ b/services/content-watcher/apps/api/tsconfig.app.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "declaration": false,
+ "outDir": "../../dist/apps/api"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
+}
diff --git a/services/content-watcher/apps/worker/src/consumer.ts b/services/content-watcher/apps/worker/src/consumer.ts
new file mode 100644
index 00000000..23fb3fee
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/consumer.ts
@@ -0,0 +1,18 @@
+import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
+import { Job } from 'bullmq';
+
+@Processor('exampleQueue', {
+ concurrency: 2,
+})
+export class ExampleConsumer extends WorkerHost {
+ // eslint-disable-next-line class-methods-use-this
+ async process(job: Job): Promise {
+ console.log(job.data);
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ onCompleted() {
+ // do some stuff
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/event.listener.ts b/services/content-watcher/apps/worker/src/event.listener.ts
new file mode 100644
index 00000000..8f9cd3cb
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/event.listener.ts
@@ -0,0 +1,19 @@
+import { QueueEventsListener, QueueEventsHost, OnQueueEvent } from '@nestjs/bullmq';
+
+@QueueEventsListener('exampleQueue')
+export class ExampleQueueEvents extends QueueEventsHost {
+ startTime: number;
+
+ constructor() {
+ super();
+ this.startTime = new Date().getTime();
+ }
+
+ @OnQueueEvent('drained')
+ onDrained({ jobId }: { jobId: string }) {
+ // do some stuff
+
+ const elapsed = new Date().getTime();
+ console.log((elapsed - this.startTime) / 1000);
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/main.ts b/services/content-watcher/apps/worker/src/main.ts
new file mode 100644
index 00000000..5663f684
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/main.ts
@@ -0,0 +1,10 @@
+import { NestFactory } from '@nestjs/core';
+import { WorkerModule } from './worker.module';
+import { WorkerService } from './worker.service';
+
+async function bootstrap() {
+ const app = await NestFactory.createApplicationContext(WorkerModule);
+ const appService = app.get(WorkerService);
+ console.log(appService.getHello());
+}
+bootstrap();
diff --git a/services/content-watcher/apps/worker/src/worker.module.ts b/services/content-watcher/apps/worker/src/worker.module.ts
new file mode 100644
index 00000000..1a33a57e
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/worker.module.ts
@@ -0,0 +1,22 @@
+import { Module } from '@nestjs/common';
+import { BullModule } from '@nestjs/bullmq';
+import { WorkerService } from './worker.service';
+import { ExampleConsumer } from './consumer';
+import { ExampleQueueEvents } from './event.listener';
+
+@Module({
+ imports: [
+ BullModule.forRoot({
+ connection: {
+ host: 'localhost',
+ port: 6379,
+ enableOfflineQueue: false,
+ },
+ }),
+ BullModule.registerQueue({
+ name: 'testQueue',
+ }),
+ ],
+ providers: [WorkerService, ExampleConsumer, ExampleQueueEvents],
+})
+export class WorkerModule {}
diff --git a/services/content-watcher/apps/worker/src/worker.service.ts b/services/content-watcher/apps/worker/src/worker.service.ts
new file mode 100644
index 00000000..bcc16565
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/worker.service.ts
@@ -0,0 +1,9 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class WorkerService {
+ // eslint-disable-next-line class-methods-use-this
+ getHello(): string {
+ return 'Hello World from Worker!';
+ }
+}
diff --git a/services/content-watcher/apps/worker/tsconfig.app.json b/services/content-watcher/apps/worker/tsconfig.app.json
new file mode 100644
index 00000000..fc3f5ed8
--- /dev/null
+++ b/services/content-watcher/apps/worker/tsconfig.app.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "declaration": false,
+ "outDir": "../../dist/apps/worker"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
+}
diff --git a/services/content-watcher/env.template b/services/content-watcher/env.template
index 410c1410..8afa0581 100644
--- a/services/content-watcher/env.template
+++ b/services/content-watcher/env.template
@@ -1,9 +1,7 @@
# Copy this file to ".env.dev" and ".env.docker.dev", and then tweak values for local development
FREQUENCY_URL=ws://0.0.0.0:9944
PROVIDER_ID=1
-PROVIDER_BASE_URL=https://some-provider/api/v1.0.0
REDIS_URL=redis://0.0.0.0:6379
-PROVIDER_ACCESS_TOKEN=some-token
BLOCKCHAIN_SCAN_INTERVAL_MINUTES=1
QUEUE_HIGH_WATER=1000
PROVIDER_ACCOUNT_SEED_PHRASE='come finish flower cinnamon blame year glad tank domain hunt release fatigue'
@@ -14,5 +12,3 @@ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS=10
HEALTH_CHECK_MAX_RETRIES=4
CAPACITY_LIMIT='{"type":"percentage", "value":80}'
-# An optional bearer token may be specified for provider authentication
-PROVIDER_ACCESS_TOKEN=some-token
diff --git a/services/content-watcher/libs/common/src/index.ts b/services/content-watcher/libs/common/src/index.ts
new file mode 100644
index 00000000..95037a7e
--- /dev/null
+++ b/services/content-watcher/libs/common/src/index.ts
@@ -0,0 +1,8 @@
+export interface LocationDto {
+ name: string;
+ accuracy?: number;
+ altitude?: number;
+ longitude?: number;
+ radius?: number;
+ units?: 'cm' | 'm' | 'km' | 'inches' | 'feet' | 'miles';
+}
diff --git a/services/content-watcher/libs/common/tsconfig.lib.json b/services/content-watcher/libs/common/tsconfig.lib.json
new file mode 100644
index 00000000..8fdbf52b
--- /dev/null
+++ b/services/content-watcher/libs/common/tsconfig.lib.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "declaration": true,
+ "outDir": "../../dist/libs/common"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
+}
diff --git a/services/content-watcher/nest-cli.json b/services/content-watcher/nest-cli.json
new file mode 100644
index 00000000..dca51c9f
--- /dev/null
+++ b/services/content-watcher/nest-cli.json
@@ -0,0 +1,37 @@
+{
+ "projects": {
+ "common": {
+ "type": "library",
+ "root": "libs/common",
+ "entryFile": "index",
+ "sourceRoot": "libs/common/src",
+ "compilerOptions": {
+ "tsConfigPath": "libs/common/tsconfig.lib.json"
+ }
+ },
+ "api": {
+ "type": "application",
+ "root": "apps/api",
+ "entryFile": "main",
+ "sourceRoot": "apps/api/src",
+ "compilerOptions": {
+ "tsConfigPath": "apps/api/tsconfig.app.json"
+ }
+ },
+ "worker": {
+ "type": "application",
+ "root": "apps/worker",
+ "entryFile": "main",
+ "sourceRoot": "apps/worker/src",
+ "compilerOptions": {
+ "tsConfigPath": "apps/worker/tsconfig.app.json"
+ }
+ }
+ },
+ "compilerOptions": {
+ "tsConfigPath": "apps/api/tsconfig.app.json"
+ },
+ "monorepo": true,
+ "root": "apps/api",
+ "sourceRoot": "apps/api/src"
+}
\ No newline at end of file
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 1f9f486e..214304b0 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -1,15 +1,14 @@
{
"name": "content-publishing-service",
- "version": "1.0.0",
+ "version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "content-publishing-service",
- "version": "1.0.0",
+ "version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
- "@dsnp/graph-sdk": "^0.0.11",
"@frequency-chain/api-augment": "1.7.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
@@ -679,14 +678,6 @@
"node": ">=12"
}
},
- "node_modules/@dsnp/graph-sdk": {
- "version": "0.0.11",
- "resolved": "https://registry.npmjs.org/@dsnp/graph-sdk/-/graph-sdk-0.0.11.tgz",
- "integrity": "sha512-GQJ+gnXLku1HyyVJfHM4CgMtv0GAi00jhNVnPlmhe5bMwkfj6Pg1ZCS8/fKgRiu8G5PAVGGCSInA/2iyBZC33g==",
- "engines": {
- "node": "^14.0.0 || ^16.0.0 || >=17.0.0"
- }
- },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"dev": true,
@@ -4177,9 +4168,10 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.14.1",
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 3148430e..7887dcf1 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -1,13 +1,13 @@
{
"name": "content-publishing-service",
- "version": "1.0.0",
- "description": "A microservice to ContentPublishing graphs in DSNP/Frequency",
- "main": "dist/src/main.js",
+ "version": "0.1.0",
+ "description": "Services to publish content on DSNP/Frequency",
+ "main": "dist/apps/api/main.js",
"scripts": {
"build": "npx tsc",
- "start": "env TS_NODE_BASEURL=./dist/src node -r tsconfig-paths/register dist/src/main.js",
- "start:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register src/main.ts",
- "start:dev:docker": "npm ci && ts-node-dev -r tsconfig-paths/register src/main.ts",
+ "start": "env TS_NODE_BASEURL=./dist/app/api node -r tsconfig-paths/register dist/apps/api/main.js",
+ "start:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
+ "start:dev:docker": "npm ci && ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
"docker-build": "docker build -t content-publishing-service .",
"docker-build:dev": "docker-compose -f docker-compose.dev.yaml build",
"docker-run": "docker build -t content-publishing-service-deploy . ; docker run -p 6379:6379 --env-file .env.dev content-publishing-service-deploy",
@@ -30,7 +30,6 @@
},
"homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
"dependencies": {
- "@dsnp/graph-sdk": "^0.0.11",
"@frequency-chain/api-augment": "1.7.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
diff --git a/services/content-watcher/tsconfig.json b/services/content-watcher/tsconfig.json
index 5a2efd47..4f5f22b5 100644
--- a/services/content-watcher/tsconfig.json
+++ b/services/content-watcher/tsconfig.json
@@ -1,38 +1,44 @@
{
- "$schema": "https://json.schemastore.org/tsconfig",
- "display": "Base",
- "compilerOptions": {
- "allowSyntheticDefaultImports": true,
- "baseUrl": "./src",
- "esModuleInterop": true,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "module": "CommonJS",
- "moduleResolution": "node",
- "noImplicitAny": false,
- "noImplicitThis": false,
- "outDir": "dist",
- "paths": {
- "#app/*": [
- "*"
- ]
- },
- "resolveJsonModule": true,
- "sourceMap": true,
- "strict": true,
- "skipLibCheck": true,
- "strictPropertyInitialization": false,
- "target": "es2022",
- "typeRoots": [
- "node_modules/@types"
- ]
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Base",
+ "compilerOptions": {
+ "allowSyntheticDefaultImports": true,
+ "baseUrl": "./src",
+ "esModuleInterop": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "module": "CommonJS",
+ "moduleResolution": "node",
+ "noImplicitAny": false,
+ "noImplicitThis": false,
+ "outDir": "dist",
+ "paths": {
+ "#app/*": [
+ "*"
+ ],
+ "@app/common": [
+ "libs/common/src"
+ ],
+ "@app/common/*": [
+ "libs/common/src/*"
+ ]
},
- "include": [
- "./**/*.ts"
- ],
- "exclude": [
- "node_modules/**",
- "./dist/**",
- "/tools/**"
+ "resolveJsonModule": true,
+ "sourceMap": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "strictPropertyInitialization": false,
+ "target": "es2022",
+ "typeRoots": [
+ "node_modules/@types"
]
-}
+ },
+ "include": [
+ "./**/*.ts"
+ ],
+ "exclude": [
+ "node_modules/**",
+ "./dist/**",
+ "/tools/**"
+ ]
+}
\ No newline at end of file
From 3245123f9575af4b1c811e060353c22c76034e08 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 23 Aug 2023 14:44:20 -0500
Subject: [PATCH 004/137] add swagger apis (#9)
* add swagger placeholder
* cleanup
* init swagger doc app
* add todo
* merge main
* api path
---
services/content-watcher/.gitignore | 2 +-
.../apps/api/src/api.controller.ts | 2 +
.../apps/api/src/config/swagger_config.ts | 20 +++++++
services/content-watcher/apps/api/src/main.ts | 2 +
services/content-watcher/package-lock.json | 58 ++++++++++++++++++-
services/content-watcher/package.json | 1 +
6 files changed, 82 insertions(+), 3 deletions(-)
create mode 100644 services/content-watcher/apps/api/src/config/swagger_config.ts
diff --git a/services/content-watcher/.gitignore b/services/content-watcher/.gitignore
index 3ad330f8..a93fd541 100644
--- a/services/content-watcher/.gitignore
+++ b/services/content-watcher/.gitignore
@@ -3,4 +3,4 @@ dist
.env*
.vscode
coverage
-.idea
\ No newline at end of file
+.idea
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index 8221f0a1..cf6f7ea9 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -1,6 +1,8 @@
import { Controller, Get, HttpStatus, Logger } from '@nestjs/common';
+import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
@Controller('api')
+@ApiTags('api')
export class ApiController {
private readonly logger: Logger;
diff --git a/services/content-watcher/apps/api/src/config/swagger_config.ts b/services/content-watcher/apps/api/src/config/swagger_config.ts
new file mode 100644
index 00000000..9b059a23
--- /dev/null
+++ b/services/content-watcher/apps/api/src/config/swagger_config.ts
@@ -0,0 +1,20 @@
+import { INestApplication } from '@nestjs/common';
+import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
+
+// TODO: Add more swagger options and document the API
+export const initSwagger = (app: INestApplication, apiPath: string) => {
+ const options = new DocumentBuilder()
+ .setTitle('Content Publishing Service API')
+ .setDescription('Content Publishing Service API')
+ .setVersion('1.0')
+ .addBearerAuth({
+ type: 'http',
+ description: 'Enter JWT token',
+ })
+ .addCookieAuth('SESSION')
+ .build();
+ const document = SwaggerModule.createDocument(app, options, {
+ extraModels: [],
+ });
+ SwaggerModule.setup(apiPath, app, document);
+};
diff --git a/services/content-watcher/apps/api/src/main.ts b/services/content-watcher/apps/api/src/main.ts
index cf1ce08c..63fe53a2 100644
--- a/services/content-watcher/apps/api/src/main.ts
+++ b/services/content-watcher/apps/api/src/main.ts
@@ -2,6 +2,7 @@ import { NestFactory } from '@nestjs/core';
import { Logger, ValidationPipe } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { ApiModule } from './api.module';
+import { initSwagger } from './config/swagger_config';
const logger = new Logger('main');
@@ -24,6 +25,7 @@ async function bootstrap() {
try {
app.enableShutdownHooks();
app.useGlobalPipes(new ValidationPipe());
+ initSwagger(app, "/api/docs/swagger");
await app.listen(3000);
} catch (e) {
await app.close();
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 214304b0..9f4c0a10 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -19,6 +19,7 @@
"@nestjs/event-emitter": "^1.4.1",
"@nestjs/platform-express": "^9.4.0",
"@nestjs/schedule": "^3.0.1",
+ "@nestjs/swagger": "^7.1.8",
"@nestjs/testing": "^9.4.0",
"@nestjs/typeorm": "^9.0.1",
"@polkadot/api": "^10.9.1",
@@ -1437,6 +1438,25 @@
"reflect-metadata": "^0.1.12"
}
},
+ "node_modules/@nestjs/mapped-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.2.tgz",
+ "integrity": "sha512-V0izw6tWs6fTp9+KiiPUbGHWALy563Frn8X6Bm87ANLRuE46iuBMD5acKBDP5lKL/75QFvrzSJT7HkCbB0jTpg==",
+ "peerDependencies": {
+ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
+ "class-transformer": "^0.4.0 || ^0.5.0",
+ "class-validator": "^0.13.0 || ^0.14.0",
+ "reflect-metadata": "^0.1.12"
+ },
+ "peerDependenciesMeta": {
+ "class-transformer": {
+ "optional": true
+ },
+ "class-validator": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@nestjs/platform-express": {
"version": "9.4.3",
"license": "MIT",
@@ -1469,6 +1489,37 @@
"reflect-metadata": "^0.1.12"
}
},
+ "node_modules/@nestjs/swagger": {
+ "version": "7.1.8",
+ "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.8.tgz",
+ "integrity": "sha512-Jpl3laGAqvyWccc3auLU0mMjl5hJ2kqzzDb63ynJi5NMbFlgBwrR8FCGBVstSsqL9YSJWLR4L1BZzVmVExcY+g==",
+ "dependencies": {
+ "@nestjs/mapped-types": "2.0.2",
+ "js-yaml": "4.1.0",
+ "lodash": "4.17.21",
+ "path-to-regexp": "3.2.0",
+ "swagger-ui-dist": "5.3.1"
+ },
+ "peerDependencies": {
+ "@fastify/static": "^6.0.0",
+ "@nestjs/common": "^9.0.0 || ^10.0.0",
+ "@nestjs/core": "^9.0.0 || ^10.0.0",
+ "class-transformer": "*",
+ "class-validator": "*",
+ "reflect-metadata": "^0.1.12"
+ },
+ "peerDependenciesMeta": {
+ "@fastify/static": {
+ "optional": true
+ },
+ "class-transformer": {
+ "optional": true
+ },
+ "class-validator": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@nestjs/testing": {
"version": "9.4.3",
"license": "MIT",
@@ -3002,7 +3053,6 @@
},
"node_modules/argparse": {
"version": "2.0.1",
- "dev": true,
"license": "Python-2.0"
},
"node_modules/array-buffer-byte-length": {
@@ -6844,7 +6894,6 @@
},
"node_modules/js-yaml": {
"version": "4.1.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -8714,6 +8763,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/swagger-ui-dist": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.3.1.tgz",
+ "integrity": "sha512-El78OvXp9zMasfPrshtkW1CRx8AugAKoZuGGOTW+8llJzOV1RtDJYqQRz/6+2OakjeWWnZuRlN2Qj1Y0ilux3w=="
+ },
"node_modules/synckit": {
"version": "0.8.5",
"dev": true,
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 7887dcf1..bd5fdb7e 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -40,6 +40,7 @@
"@nestjs/event-emitter": "^1.4.1",
"@nestjs/platform-express": "^9.4.0",
"@nestjs/schedule": "^3.0.1",
+ "@nestjs/swagger": "^7.1.8",
"@nestjs/testing": "^9.4.0",
"@nestjs/typeorm": "^9.0.1",
"@polkadot/api": "^10.9.1",
From c3d23bca2eda74ae93e978a419507c10bcd4d53d Mon Sep 17 00:00:00 2001
From: Aramik
Date: Fri, 25 Aug 2023 13:39:39 -0700
Subject: [PATCH 005/137] define api endpoints and contract (#15)
* define api endpoints and contract
* minor description for swagger
* some PR feedback
* update swagger
---
.../apps/api/src/api.controller.ts | 78 +-
.../apps/api/src/config/swagger_config.ts | 5 +-
.../apps/api/src/generate-metadata.ts | 10 +
services/content-watcher/apps/api/src/main.ts | 2 +-
.../content-watcher/apps/api/src/metadata.ts | 9 +
.../libs/common/src/dtos/activity.dto.ts | 98 +
.../libs/common/src/dtos/announcement.dto.ts | 43 +
.../libs/common/src/dtos/common.dto.ts | 18 +
.../content-watcher/libs/common/src/index.ts | 11 +-
services/content-watcher/package-lock.json | 1863 ++++++++++++++++-
services/content-watcher/package.json | 4 +
11 files changed, 2080 insertions(+), 61 deletions(-)
create mode 100644 services/content-watcher/apps/api/src/generate-metadata.ts
create mode 100644 services/content-watcher/apps/api/src/metadata.ts
create mode 100644 services/content-watcher/libs/common/src/dtos/activity.dto.ts
create mode 100644 services/content-watcher/libs/common/src/dtos/announcement.dto.ts
create mode 100644 services/content-watcher/libs/common/src/dtos/common.dto.ts
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index cf6f7ea9..369d2916 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -1,8 +1,10 @@
-import { Controller, Get, HttpStatus, Logger } from '@nestjs/common';
-import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
+import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, Post, Put, UploadedFile, UploadedFiles, UseInterceptors } from '@nestjs/common';
+import { v4 as uuidv4 } from 'uuid';
+import { FilesInterceptor } from '@nestjs/platform-express';
+import { ApiBody, ApiConsumes } from '@nestjs/swagger';
+import { BroadcastDto, ReactionDto, ReplyDto, UpdateDto, ProfileDto, AnnouncementResponseDto, FilesUploadDto, UploadResponseDto } from '../../../libs/common/src';
@Controller('api')
-@ApiTags('api')
export class ApiController {
private readonly logger: Logger;
@@ -17,4 +19,74 @@ export class ApiController {
status: HttpStatus.OK,
};
}
+
+ @Put('asset/upload')
+ @UseInterceptors(FilesInterceptor('files'))
+ @HttpCode(202)
+ @ApiConsumes('multipart/form-data')
+ @ApiBody({
+ description: 'Asset files',
+ type: FilesUploadDto,
+ })
+ // eslint-disable-next-line no-undef
+ async assetUpload(@UploadedFiles() files: Array): Promise {
+ this.logger.log(`upload ${files.length}`);
+ return {
+ assetIds: files.map((_) => uuidv4()),
+ };
+ }
+
+ @Post('content/:userDsnpId/broadcast')
+ @HttpCode(202)
+ async broadcast(@Param('userDsnpId') userDsnpId: string, @Body() broadcastDto: BroadcastDto): Promise {
+ this.logger.log(`broadcast ${userDsnpId}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
+
+ @Post('content/:userDsnpId/reply')
+ @HttpCode(202)
+ async reply(@Param('userDsnpId') userDsnpId: string, @Body() replyDto: ReplyDto): Promise {
+ this.logger.log(`reply ${userDsnpId}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
+
+ @Post('content/:userDsnpId/reaction')
+ @HttpCode(202)
+ async reaction(@Param('userDsnpId') userDsnpId: string, @Body() reactionDto: ReactionDto): Promise {
+ this.logger.log(`reaction ${userDsnpId}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
+
+ @Put('content/:userDsnpId/:targetContentHash')
+ @HttpCode(202)
+ async update(@Param('userDsnpId') userDsnpId: string, @Param('targetContentHash') targetContentHash: string, @Body() updateDto: UpdateDto): Promise {
+ this.logger.log(`update ${userDsnpId}/${targetContentHash}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
+
+ @Delete('content/:userDsnpId/:targetContentHash')
+ @HttpCode(202)
+ async delete(@Param('userDsnpId') userDsnpId: string, @Param('targetContentHash') targetContentHash: string): Promise {
+ this.logger.log(`delete ${userDsnpId}/${targetContentHash}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
+
+ @Put('profile/:userDsnpId')
+ @HttpCode(202)
+ async profile(@Param('userDsnpId') userDsnpId: string, @Body() profileDto: ProfileDto): Promise {
+ this.logger.log(`profile ${userDsnpId}`);
+ return {
+ referenceId: uuidv4(),
+ };
+ }
}
diff --git a/services/content-watcher/apps/api/src/config/swagger_config.ts b/services/content-watcher/apps/api/src/config/swagger_config.ts
index 9b059a23..2c6b98e1 100644
--- a/services/content-watcher/apps/api/src/config/swagger_config.ts
+++ b/services/content-watcher/apps/api/src/config/swagger_config.ts
@@ -1,8 +1,8 @@
import { INestApplication } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
+import metadata from '../metadata';
-// TODO: Add more swagger options and document the API
-export const initSwagger = (app: INestApplication, apiPath: string) => {
+export const initSwagger = async (app: INestApplication, apiPath: string) => {
const options = new DocumentBuilder()
.setTitle('Content Publishing Service API')
.setDescription('Content Publishing Service API')
@@ -13,6 +13,7 @@ export const initSwagger = (app: INestApplication, apiPath: string) => {
})
.addCookieAuth('SESSION')
.build();
+ await SwaggerModule.loadPluginMetadata(metadata);
const document = SwaggerModule.createDocument(app, options, {
extraModels: [],
});
diff --git a/services/content-watcher/apps/api/src/generate-metadata.ts b/services/content-watcher/apps/api/src/generate-metadata.ts
new file mode 100644
index 00000000..10f263f1
--- /dev/null
+++ b/services/content-watcher/apps/api/src/generate-metadata.ts
@@ -0,0 +1,10 @@
+import { PluginMetadataGenerator } from '@nestjs/cli/lib/compiler/plugins';
+import { ReadonlyVisitor } from '@nestjs/swagger/dist/plugin';
+
+const generator = new PluginMetadataGenerator();
+generator.generate({
+ visitors: [new ReadonlyVisitor({ introspectComments: true, pathToSource: __dirname })],
+ outputDir: __dirname,
+ watch: false,
+ tsconfigPath: 'apps/api/tsconfig.app.json',
+});
diff --git a/services/content-watcher/apps/api/src/main.ts b/services/content-watcher/apps/api/src/main.ts
index 63fe53a2..8cba5acd 100644
--- a/services/content-watcher/apps/api/src/main.ts
+++ b/services/content-watcher/apps/api/src/main.ts
@@ -25,7 +25,7 @@ async function bootstrap() {
try {
app.enableShutdownHooks();
app.useGlobalPipes(new ValidationPipe());
- initSwagger(app, "/api/docs/swagger");
+ await initSwagger(app, '/api/docs/swagger');
await app.listen(3000);
} catch (e) {
await app.close();
diff --git a/services/content-watcher/apps/api/src/metadata.ts b/services/content-watcher/apps/api/src/metadata.ts
new file mode 100644
index 00000000..91a614a2
--- /dev/null
+++ b/services/content-watcher/apps/api/src/metadata.ts
@@ -0,0 +1,9 @@
+/* eslint-disable */
+export default async () => {
+ const t = {
+ ["../../../libs/common/src/dtos/activity.dto"]: await import("../../../libs/common/src/dtos/activity.dto"),
+ ["../../../libs/common/src/dtos/announcement.dto"]: await import("../../../libs/common/src/dtos/announcement.dto"),
+ ["../../../libs/common/src/dtos/common.dto"]: await import("../../../libs/common/src/dtos/common.dto")
+ };
+ return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LinkDto": { href: { required: true, type: () => String }, name: { required: false, type: () => String } }, "LocationDto": { name: { required: true, type: () => String }, accuracy: { required: false, type: () => Number }, altitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String }, height: { required: false, type: () => Number }, width: { required: false, type: () => Number }, duration: { required: false, type: () => String } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String }, mentionedId: { required: false, type: () => String } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: true, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String }, href: { required: false, type: () => String } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String }, published: { required: true, type: () => String }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].AnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String }, apply: { required: true, type: () => Number }, inReplyTo: { required: true, type: () => String } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }]] } };
+};
\ No newline at end of file
diff --git a/services/content-watcher/libs/common/src/dtos/activity.dto.ts b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
new file mode 100644
index 00000000..1b37f27a
--- /dev/null
+++ b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
@@ -0,0 +1,98 @@
+/**
+ * File name should always end with `.dto.ts` for swagger metadata generator to get picked up
+ */
+// eslint-disable-next-line no-shadow,max-classes-per-file
+export enum UnitTypeDto {
+ CM = 'cm',
+ M = 'm',
+ KM = 'km',
+ INCHES = 'inches',
+ FEET = 'feet',
+ MILES = 'miles',
+}
+
+// eslint-disable-next-line no-shadow
+export enum TagTypeDto {
+ Mention = 'mention',
+ Hashtag = 'hashtag',
+}
+
+// eslint-disable-next-line no-shadow
+export enum AttachmentTypeDto {
+ LINK = 'link',
+ IMAGE = 'image',
+ AUDIO = 'audio',
+ VIDEO = 'video',
+}
+
+export class LinkDto {
+ href: string;
+
+ name?: string;
+}
+
+export class LocationDto {
+ name: string;
+
+ accuracy?: number;
+
+ altitude?: number;
+
+ longitude?: number;
+
+ radius?: number;
+
+ units?: UnitTypeDto;
+}
+
+export class AssetReferenceDto {
+ referenceId: string;
+
+ height?: number;
+
+ width?: number;
+
+ duration?: string;
+}
+
+export class TagDto {
+ type: TagTypeDto;
+
+ name?: string;
+
+ mentionedId?: string;
+}
+
+export class AssetDto {
+ type: AttachmentTypeDto;
+
+ references: Array;
+
+ name?: string;
+
+ href?: string;
+}
+
+export class BaseActivityDto {
+ name?: string;
+
+ tag?: Array;
+
+ location?: LocationDto;
+}
+
+export class NoteActivityDto extends BaseActivityDto {
+ content: string;
+
+ published: string;
+
+ assets?: Array;
+}
+
+export class ProfileActivityDto extends BaseActivityDto {
+ icon?: Array;
+
+ summary?: string;
+
+ published?: string;
+}
diff --git a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
new file mode 100644
index 00000000..f684c4e1
--- /dev/null
+++ b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
@@ -0,0 +1,43 @@
+/**
+ * File name should always end with `.dto.ts` for swagger metadata generator to get picked up
+ */
+// eslint-disable-next-line max-classes-per-file
+import { NoteActivityDto, ProfileActivityDto } from './activity.dto';
+
+// eslint-disable-next-line no-shadow
+export enum AnnouncementTypeDto {
+ TOMBSTONE = 'tombstone',
+ BROADCAST = 'broadcast',
+ REPLY = 'reply',
+ REACTION = 'reaction',
+ PROFILE = 'profile',
+ UPDATE = 'update',
+}
+
+export class BroadcastDto {
+ content: NoteActivityDto;
+}
+
+export class ReplyDto {
+ inReplyTo: string;
+
+ content: NoteActivityDto;
+}
+
+export class UpdateDto {
+ targetAnnouncementType: AnnouncementTypeDto;
+
+ content: NoteActivityDto;
+}
+
+export class ReactionDto {
+ emoji: string;
+
+ apply: number;
+
+ inReplyTo: string;
+}
+
+export class ProfileDto {
+ profile: ProfileActivityDto;
+}
diff --git a/services/content-watcher/libs/common/src/dtos/common.dto.ts b/services/content-watcher/libs/common/src/dtos/common.dto.ts
new file mode 100644
index 00000000..9fd836aa
--- /dev/null
+++ b/services/content-watcher/libs/common/src/dtos/common.dto.ts
@@ -0,0 +1,18 @@
+/**
+ * File name should always end with `.dto.ts` for swagger metadata generator to get picked up
+ */
+// eslint-disable-next-line max-classes-per-file
+import { ApiProperty } from '@nestjs/swagger';
+
+export class AnnouncementResponseDto {
+ referenceId: string;
+}
+
+export class UploadResponseDto {
+ assetIds: Array;
+}
+
+export class FilesUploadDto {
+ @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
+ files: any[];
+}
diff --git a/services/content-watcher/libs/common/src/index.ts b/services/content-watcher/libs/common/src/index.ts
index 95037a7e..9e674f38 100644
--- a/services/content-watcher/libs/common/src/index.ts
+++ b/services/content-watcher/libs/common/src/index.ts
@@ -1,8 +1,3 @@
-export interface LocationDto {
- name: string;
- accuracy?: number;
- altitude?: number;
- longitude?: number;
- radius?: number;
- units?: 'cm' | 'm' | 'km' | 'inches' | 'feet' | 'miles';
-}
+export * from './dtos/announcement.dto';
+export * from './dtos/activity.dto';
+export * from './dtos/common.dto';
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 9f4c0a10..f26ec156 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -28,6 +28,8 @@
"@polkadot/types": "^10.9.1",
"@polkadot/util": "^12.3.2",
"@polkadot/util-crypto": "^12.3.2",
+ "@types/multer": "^1.4.7",
+ "@types/uuid": "^9.0.2",
"axios": "^1.3.6",
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
@@ -39,6 +41,7 @@
},
"devDependencies": {
"@jest/globals": "^29.5.0",
+ "@nestjs/cli": "^10.1.14",
"@polkadot/typegen": "10.9.1",
"@types/jest": "^29.5.2",
"@types/time-constants": "^1.0.0",
@@ -83,6 +86,129 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@angular-devkit/core": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.0.tgz",
+ "integrity": "sha512-l1k6Rqm3YM16BEn3CWyQKrk9xfu+2ux7Bw3oS+h1TO4/RoxO2PgHj8LLRh/WNrYVarhaqO7QZ5ePBkXNMkzJ1g==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "8.12.0",
+ "ajv-formats": "2.1.1",
+ "jsonc-parser": "3.2.0",
+ "rxjs": "7.8.1",
+ "source-map": "0.7.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.10.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ },
+ "peerDependencies": {
+ "chokidar": "^3.5.2"
+ },
+ "peerDependenciesMeta": {
+ "chokidar": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@angular-devkit/core/node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/@angular-devkit/core/node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@angular-devkit/schematics": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.0.tgz",
+ "integrity": "sha512-QMDJXPE0+YQJ9Ap3MMzb0v7rx6ZbBEokmHgpdIjN3eILYmbAdsSGE8HTV8NjS9nKmcyE9OGzFCMb7PFrDTlTAw==",
+ "dev": true,
+ "dependencies": {
+ "@angular-devkit/core": "16.2.0",
+ "jsonc-parser": "3.2.0",
+ "magic-string": "0.30.1",
+ "ora": "5.4.1",
+ "rxjs": "7.8.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.10.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@angular-devkit/schematics-cli": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.2.0.tgz",
+ "integrity": "sha512-f3HjrDvSrRMvESogLsqsZXsEg//trIBySCHRXCglPrWLVdBbIRctGOhXqZoclRxXimIKUx14zLsOWzDwZG8+HQ==",
+ "dev": true,
+ "dependencies": {
+ "@angular-devkit/core": "16.2.0",
+ "@angular-devkit/schematics": "16.2.0",
+ "ansi-colors": "4.1.3",
+ "inquirer": "8.2.4",
+ "symbol-observable": "4.0.0",
+ "yargs-parser": "21.1.1"
+ },
+ "bin": {
+ "schematics": "bin/schematics.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.10.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": {
+ "version": "8.2.4",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
+ "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.1",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.21",
+ "mute-stream": "0.0.8",
+ "ora": "^5.4.1",
+ "run-async": "^2.4.0",
+ "rxjs": "^7.5.5",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.22.5",
"dev": true,
@@ -668,6 +794,16 @@
"license": "MIT",
"peer": true
},
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"devOptional": true,
@@ -1255,6 +1391,16 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"devOptional": true,
@@ -1334,6 +1480,114 @@
"bullmq": "^3.0.0"
}
},
+ "node_modules/@nestjs/cli": {
+ "version": "10.1.14",
+ "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.1.14.tgz",
+ "integrity": "sha512-oxfoebzrq6g+MKc6FRx2O8D86Vk0ViEmlP4B1E3dzwC3X5yjxlA1IDulLrVz3VIpGjuyuXmrQjjd8l0NUVZiKg==",
+ "dev": true,
+ "dependencies": {
+ "@angular-devkit/core": "16.2.0",
+ "@angular-devkit/schematics": "16.2.0",
+ "@angular-devkit/schematics-cli": "16.2.0",
+ "@nestjs/schematics": "^10.0.1",
+ "chalk": "4.1.2",
+ "chokidar": "3.5.3",
+ "cli-table3": "0.6.3",
+ "commander": "4.1.1",
+ "fork-ts-checker-webpack-plugin": "8.0.0",
+ "inquirer": "8.2.6",
+ "node-emoji": "1.11.0",
+ "ora": "5.4.1",
+ "os-name": "4.0.1",
+ "rimraf": "4.4.1",
+ "shelljs": "0.8.5",
+ "source-map-support": "0.5.21",
+ "tree-kill": "1.2.2",
+ "tsconfig-paths": "4.2.0",
+ "tsconfig-paths-webpack-plugin": "4.1.0",
+ "typescript": "5.1.6",
+ "webpack": "5.88.2",
+ "webpack-node-externals": "3.0.0"
+ },
+ "bin": {
+ "nest": "bin/nest.js"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "peerDependencies": {
+ "@swc/cli": "^0.1.62",
+ "@swc/core": "^1.3.62"
+ },
+ "peerDependenciesMeta": {
+ "@swc/cli": {
+ "optional": true
+ },
+ "@swc/core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/cli/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@nestjs/cli/node_modules/glob": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@nestjs/cli/node_modules/minimatch": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@nestjs/cli/node_modules/rimraf": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz",
+ "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^9.2.0"
+ },
+ "bin": {
+ "rimraf": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/@nestjs/common": {
"version": "9.4.3",
"license": "MIT",
@@ -1489,6 +1743,109 @@
"reflect-metadata": "^0.1.12"
}
},
+ "node_modules/@nestjs/schematics": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.0.2.tgz",
+ "integrity": "sha512-DaZZjymYoIfRqC5W62lnYXIIods1PDY6CGc8+IpRwyinzffjKxZ3DF3exu+mdyvllzkXo9DTXkoX4zOPSJHCkw==",
+ "dev": true,
+ "dependencies": {
+ "@angular-devkit/core": "16.1.8",
+ "@angular-devkit/schematics": "16.1.8",
+ "comment-json": "4.2.3",
+ "jsonc-parser": "3.2.0",
+ "pluralize": "8.0.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.2"
+ }
+ },
+ "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": {
+ "version": "16.1.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.8.tgz",
+ "integrity": "sha512-dSRD/+bGanArIXkj+kaU1kDFleZeQMzmBiOXX+pK0Ah9/0Yn1VmY3RZh1zcX9vgIQXV+t7UPrTpOjaERMUtVGw==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "8.12.0",
+ "ajv-formats": "2.1.1",
+ "jsonc-parser": "3.2.0",
+ "rxjs": "7.8.1",
+ "source-map": "0.7.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.10.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ },
+ "peerDependencies": {
+ "chokidar": "^3.5.2"
+ },
+ "peerDependenciesMeta": {
+ "chokidar": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": {
+ "version": "16.1.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.8.tgz",
+ "integrity": "sha512-6LyzMdFJs337RTxxkI2U1Ndw0CW5mMX/aXWl8d7cW2odiSrAg8IdlMqpc+AM8+CPfsB0FtS1aWkEZqJLT0jHOg==",
+ "dev": true,
+ "dependencies": {
+ "@angular-devkit/core": "16.1.8",
+ "jsonc-parser": "3.2.0",
+ "magic-string": "0.30.0",
+ "ora": "5.4.1",
+ "rxjs": "7.8.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.10.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@nestjs/schematics/node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@nestjs/schematics/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/@nestjs/schematics/node_modules/magic-string": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
+ "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.13"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@nestjs/schematics/node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/@nestjs/swagger": {
"version": "7.1.8",
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.1.8.tgz",
@@ -2396,6 +2753,71 @@
"@types/node": "*"
}
},
+ "node_modules/@types/body-parser": {
+ "version": "1.19.2",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
+ "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "8.44.2",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz",
+ "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
+ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
+ "dev": true
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.17",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
+ "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.17.36",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz",
+ "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.6",
"dev": true,
@@ -2409,6 +2831,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ=="
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
"dev": true,
@@ -2442,29 +2869,76 @@
"node_modules/@types/json-schema": {
"version": "7.0.12",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/json5": {
"version": "0.0.29",
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/mime": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
+ },
+ "node_modules/@types/multer": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
+ "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "20.2.5",
"license": "MIT"
},
+ "node_modules/@types/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+ "dev": true
+ },
"node_modules/@types/prettier": {
"version": "2.7.3",
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
+ },
"node_modules/@types/semver": {
"version": "7.5.0",
"dev": true,
"license": "MIT",
"peer": true
},
+ "node_modules/@types/send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
+ "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"dev": true,
@@ -2485,6 +2959,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/uuid": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz",
+ "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ=="
+ },
"node_modules/@types/validator": {
"version": "13.7.17",
"license": "MIT"
@@ -2917,39 +3396,206 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/accepts": {
- "version": "1.3.8",
- "license": "MIT",
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "dev": true,
"dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
}
},
- "node_modules/acorn": {
- "version": "8.8.2",
- "devOptional": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@xtuc/long": "4.2.2"
}
},
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
"dev": true,
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
}
},
- "node_modules/acorn-walk": {
- "version": "8.2.0",
- "devOptional": true,
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "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"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@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"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "devOptional": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-assertions": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.4.0"
@@ -2970,11 +3616,67 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/ansi-escapes": {
"version": "4.3.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"type-fest": "^0.21.3"
},
@@ -2989,7 +3691,6 @@
"version": "0.21.3",
"dev": true,
"license": "(MIT OR CC0-1.0)",
- "peer": true,
"engines": {
"node": ">=10"
},
@@ -3089,6 +3790,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/array-timsort": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
+ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
+ "dev": true
+ },
"node_modules/array-union": {
"version": "2.1.0",
"dev": true,
@@ -3270,8 +3977,7 @@
"url": "https://feross.org/support"
}
],
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/big-integer": {
"version": "1.6.51",
@@ -3289,6 +3995,55 @@
"node": ">=8"
}
},
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bl/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/bl/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/bn.js": {
"version": "5.2.1",
"license": "MIT"
@@ -3634,6 +4389,12 @@
"node": ">=10"
}
},
+ "node_modules/chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
"node_modules/chokidar": {
"version": "3.5.3",
"dev": true,
@@ -3671,6 +4432,15 @@
"node": ">= 6"
}
},
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
"node_modules/ci-info": {
"version": "3.8.0",
"dev": true,
@@ -3704,6 +4474,18 @@
"validator": "^13.7.0"
}
},
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/cli-highlight": {
"version": "2.1.11",
"license": "ISC",
@@ -3759,6 +4541,42 @@
"node": ">=10"
}
},
+ "node_modules/cli-spinners": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz",
+ "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
+ "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/cliui": {
"version": "8.0.1",
"license": "ISC",
@@ -3771,6 +4589,15 @@
"node": ">=12"
}
},
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"license": "Apache-2.0",
@@ -3818,6 +4645,31 @@
"node": ">= 0.8"
}
},
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/comment-json": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz",
+ "integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==",
+ "dev": true,
+ "dependencies": {
+ "array-timsort": "^1.0.3",
+ "core-util-is": "^1.0.3",
+ "esprima": "^4.0.1",
+ "has-own-prop": "^2.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"dev": true,
@@ -3893,6 +4745,22 @@
"node": ">= 0.10"
}
},
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dev": true,
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/create-require": {
"version": "1.1.1",
"devOptional": true,
@@ -4013,7 +4881,6 @@
"version": "4.3.1",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -4050,6 +4917,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "dev": true,
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/defer-to-connect": {
"version": "2.0.1",
"dev": true,
@@ -4217,6 +5096,15 @@
"node": ">= 0.8"
}
},
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@@ -4239,7 +5127,6 @@
"version": "1.3.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
@@ -4291,6 +5178,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es-module-lexer": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
+ "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
+ "dev": true
+ },
"node_modules/es-set-tostringtag": {
"version": "2.0.1",
"dev": true,
@@ -4744,7 +5637,6 @@
"version": "5.1.1",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -4882,7 +5774,6 @@
"version": "4.3.0",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"engines": {
"node": ">=4.0"
}
@@ -4910,6 +5801,15 @@
"version": "5.0.1",
"license": "MIT"
},
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
"node_modules/execa": {
"version": "7.1.1",
"dev": true,
@@ -5045,6 +5945,20 @@
"node": ">= 0.8"
}
},
+ "node_modules/external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "dependencies": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"dev": true,
@@ -5132,6 +6046,30 @@
"node": "^12.20 || >= 14.13"
}
},
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/figures/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"dev": true,
@@ -5239,6 +6177,34 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/fork-ts-checker-webpack-plugin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz",
+ "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.16.7",
+ "chalk": "^4.1.2",
+ "chokidar": "^3.5.3",
+ "cosmiconfig": "^7.0.1",
+ "deepmerge": "^4.2.2",
+ "fs-extra": "^10.0.0",
+ "memfs": "^3.4.1",
+ "minimatch": "^3.0.4",
+ "node-abort-controller": "^3.0.1",
+ "schema-utils": "^3.1.1",
+ "semver": "^7.3.5",
+ "tapable": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=12.13.0",
+ "yarn": ">=1.0.0"
+ },
+ "peerDependencies": {
+ "typescript": ">3.6.0",
+ "webpack": "^5.11.0"
+ }
+ },
"node_modules/form-data": {
"version": "4.0.0",
"license": "MIT",
@@ -5283,6 +6249,26 @@
"node": ">= 0.6"
}
},
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/fs-monkey": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz",
+ "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==",
+ "dev": true
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"license": "ISC"
@@ -5436,6 +6422,12 @@
"node": ">=10.13.0"
}
},
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
"node_modules/globals": {
"version": "13.20.0",
"dev": true,
@@ -5579,6 +6571,15 @@
"node": ">=8"
}
},
+ "node_modules/has-own-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
+ "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/has-property-descriptors": {
"version": "1.0.0",
"dev": true,
@@ -5703,8 +6704,7 @@
"url": "https://feross.org/support"
}
],
- "license": "BSD-3-Clause",
- "peer": true
+ "license": "BSD-3-Clause"
},
"node_modules/ignore": {
"version": "5.2.4",
@@ -5773,6 +6773,46 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/inquirer": {
+ "version": "8.2.6",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
+ "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.1",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.21",
+ "mute-stream": "0.0.8",
+ "ora": "^5.4.1",
+ "run-async": "^2.4.0",
+ "rxjs": "^7.5.5",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6",
+ "wrap-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/inquirer/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/internal-slot": {
"version": "1.0.5",
"dev": true,
@@ -5786,6 +6826,15 @@
"node": ">= 0.4"
}
},
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/ioredis": {
"version": "5.3.2",
"license": "MIT",
@@ -5831,8 +6880,7 @@
"node_modules/is-arrayish": {
"version": "0.2.1",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/is-bigint": {
"version": "1.0.4",
@@ -5973,6 +7021,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-negative-zero": {
"version": "2.0.2",
"dev": true,
@@ -6097,6 +7154,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-weakref": {
"version": "1.0.2",
"dev": true,
@@ -6921,8 +7990,7 @@
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
@@ -6949,6 +8017,24 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.2",
"dev": true,
@@ -7016,8 +8102,16 @@
"node_modules/lines-and-columns": {
"version": "1.2.4",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
},
"node_modules/locate-path": {
"version": "6.0.0",
@@ -7061,6 +8155,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/lower-case": {
"version": "2.0.2",
"dev": true,
@@ -7097,6 +8207,30 @@
"node": ">=12"
}
},
+ "node_modules/macos-release": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz",
+ "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.1",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz",
+ "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/make-dir": {
"version": "3.1.0",
"dev": true,
@@ -7141,6 +8275,18 @@
"node": ">= 0.6"
}
},
+ "node_modules/memfs": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
+ "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
+ "dev": true,
+ "dependencies": {
+ "fs-monkey": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
"node_modules/merge-descriptors": {
"version": "1.0.1",
"license": "MIT"
@@ -7244,6 +8390,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/mkdirp": {
"version": "0.5.6",
"license": "MIT",
@@ -7308,6 +8463,12 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
"node_modules/mz": {
"version": "2.7.0",
"license": "MIT",
@@ -7363,6 +8524,12 @@
"node": ">= 10.13"
}
},
+ "node_modules/node-abort-controller": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
+ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
+ "dev": true
+ },
"node_modules/node-domexception": {
"version": "1.0.0",
"funding": [
@@ -7380,6 +8547,15 @@
"node": ">=10.5.0"
}
},
+ "node_modules/node-emoji": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
+ "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.21"
+ }
+ },
"node_modules/node-fetch": {
"version": "3.3.1",
"license": "MIT",
@@ -7592,6 +8768,54 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "dev": true,
+ "dependencies": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/os-name": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz",
+ "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==",
+ "dev": true,
+ "dependencies": {
+ "macos-release": "^2.5.0",
+ "windows-release": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/p-cancelable": {
"version": "3.0.0",
"dev": true,
@@ -7656,7 +8880,6 @@
"version": "5.2.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -7724,6 +8947,40 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/path-scurry": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
+ "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
+ "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz",
+ "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
"node_modules/path-to-regexp": {
"version": "3.2.0",
"license": "MIT"
@@ -7824,6 +9081,15 @@
"node": ">=8"
}
},
+ "node_modules/pluralize": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
+ "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"dev": true,
@@ -7921,6 +9187,16 @@
"version": "1.1.0",
"license": "MIT"
},
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.0",
"dev": true,
@@ -7988,6 +9264,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"license": "MIT",
@@ -8063,6 +9348,18 @@
"node": ">=8.10.0"
}
},
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/redis": {
"version": "4.6.7",
"license": "MIT",
@@ -8134,6 +9431,15 @@
"url": "https://github.com/sponsors/mysticatea"
}
},
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/require-directory": {
"version": "2.1.1",
"license": "MIT",
@@ -8141,6 +9447,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/resolve": {
"version": "1.22.2",
"dev": true,
@@ -8222,6 +9537,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/reusify": {
"version": "1.0.4",
"dev": true,
@@ -8341,6 +9693,15 @@
"node": ">=6"
}
},
+ "node_modules/run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"dev": true,
@@ -8406,6 +9767,24 @@
"version": "2.1.2",
"license": "MIT"
},
+ "node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/semver": {
"version": "7.5.3",
"license": "ISC",
@@ -8466,6 +9845,15 @@
"upper-case-first": "^2.0.2"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
"node_modules/serve-static": {
"version": "1.15.0",
"license": "MIT",
@@ -8514,6 +9902,23 @@
"node": ">=8"
}
},
+ "node_modules/shelljs": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/side-channel": {
"version": "1.0.4",
"license": "MIT",
@@ -8768,6 +10173,15 @@
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.3.1.tgz",
"integrity": "sha512-El78OvXp9zMasfPrshtkW1CRx8AugAKoZuGGOTW+8llJzOV1RtDJYqQRz/6+2OakjeWWnZuRlN2Qj1Y0ilux3w=="
},
+ "node_modules/symbol-observable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
+ "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/synckit": {
"version": "0.8.5",
"dev": true,
@@ -8803,6 +10217,103 @@
"node": ">=6"
}
},
+ "node_modules/terser": {
+ "version": "5.19.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
+ "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.16.8"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
"node_modules/test-exclude": {
"version": "6.0.0",
"dev": true,
@@ -8840,6 +10351,12 @@
"node": ">=0.8"
}
},
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true
+ },
"node_modules/time-constants": {
"version": "1.0.3",
"license": "ISC"
@@ -8855,6 +10372,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
"node_modules/tmpl": {
"version": "1.0.5",
"dev": true,
@@ -9061,6 +10590,20 @@
"node": ">=6"
}
},
+ "node_modules/tsconfig-paths-webpack-plugin": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz",
+ "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "enhanced-resolve": "^5.7.0",
+ "tsconfig-paths": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/tsconfig/node_modules/strip-json-comments": {
"version": "2.0.1",
"dev": true,
@@ -9307,9 +10850,10 @@
}
},
"node_modules/typescript": {
- "version": "5.1.3",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
+ "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
"devOptional": true,
- "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -9354,6 +10898,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"license": "MIT",
@@ -9427,7 +10980,8 @@
},
"node_modules/uuid": {
"version": "9.0.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
+ "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
"bin": {
"uuid": "dist/bin/uuid"
}
@@ -9509,6 +11063,28 @@
"makeerror": "1.0.12"
}
},
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "dev": true,
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"license": "MIT",
@@ -9520,6 +11096,71 @@
"version": "3.0.1",
"license": "BSD-2-Clause"
},
+ "node_modules/webpack": {
+ "version": "5.88.2",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+ "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^1.0.0",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.9.0",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.2.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.7",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-node-externals": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz",
+ "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/whatwg-url": {
"version": "5.0.0",
"license": "MIT",
@@ -9576,6 +11217,125 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/windows-release": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz",
+ "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==",
+ "dev": true,
+ "dependencies": {
+ "execa": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/windows-release/node_modules/execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/windows-release/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/windows-release/node_modules/human-signals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.12.0"
+ }
+ },
+ "node_modules/windows-release/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/windows-release/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/windows-release/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/windows-release/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/windows-release/node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/wordwrap": {
"version": "1.0.0",
"dev": true,
@@ -9649,6 +11409,15 @@
"version": "4.0.0",
"license": "ISC"
},
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/yargs": {
"version": "17.7.2",
"license": "MIT",
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index bd5fdb7e..5505a040 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -5,6 +5,7 @@
"main": "dist/apps/api/main.js",
"scripts": {
"build": "npx tsc",
+ "build:swagger": "npx ts-node apps/api/src/generate-metadata.ts",
"start": "env TS_NODE_BASEURL=./dist/app/api node -r tsconfig-paths/register dist/apps/api/main.js",
"start:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
"start:dev:docker": "npm ci && ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
@@ -36,6 +37,7 @@
"@nestjs/bullmq": "^10.0.0",
"@nestjs/common": "^9.4.0",
"@nestjs/config": "^2.3.1",
+ "@nestjs/cli": "^10.1.14",
"@nestjs/core": "^9.4.0",
"@nestjs/event-emitter": "^1.4.1",
"@nestjs/platform-express": "^9.4.0",
@@ -49,6 +51,8 @@
"@polkadot/types": "^10.9.1",
"@polkadot/util": "^12.3.2",
"@polkadot/util-crypto": "^12.3.2",
+ "@types/multer": "^1.4.7",
+ "@types/uuid": "^9.0.2",
"axios": "^1.3.6",
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
From 99dc51f1723b51ab7aa9ad03b24d41be1077fde9 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Tue, 29 Aug 2023 08:33:48 -0500
Subject: [PATCH 006/137] Publisher Processor (#14)
* base work
* set up interface
* setup interfaces
* setup publisher
* implement publish to publish a batch
* lint
* add TODOs
* cleanups
* refactor
* update worker, refactor blockchain module
* fix worker and imports
* add placeholder files for tests
* cleanup and address feedback
* cleanups
---
.../apps/api/src/api.module.ts | 2 -
.../src/blockchain/blockchain-constants.ts | 0
.../src/blockchain/blockchain.module.ts | 2 +-
.../src/blockchain/blockchain.service.spec.ts | 18 +
.../src/blockchain/blockchain.service.ts | 6 +-
.../src/blockchain/create-keys.ts | 0
.../src/blockchain/event-error.ts | 0
.../src/blockchain/extrinsic.ts | 2 +-
.../src/interfaces/publisher-job.interface.ts | 10 +
.../src/publisher/ipfs.publisher.spec.ts | 30 ++
.../worker/src/publisher/ipfs.publisher.ts | 86 ++++
.../worker/src/publisher/publisher.module.ts | 69 +++
.../src/publisher/publishing.service.ts | 161 +++++++
.../apps/worker/src/worker.module.ts | 51 ++-
.../libs/common/src/constants.ts | 2 +
services/content-watcher/package-lock.json | 395 ++----------------
services/content-watcher/package.json | 2 +-
17 files changed, 448 insertions(+), 388 deletions(-)
rename services/content-watcher/apps/{api => worker}/src/blockchain/blockchain-constants.ts (100%)
rename services/content-watcher/apps/{api => worker}/src/blockchain/blockchain.module.ts (80%)
create mode 100644 services/content-watcher/apps/worker/src/blockchain/blockchain.service.spec.ts
rename services/content-watcher/apps/{api => worker}/src/blockchain/blockchain.service.ts (96%)
rename services/content-watcher/apps/{api => worker}/src/blockchain/create-keys.ts (100%)
rename services/content-watcher/apps/{api => worker}/src/blockchain/event-error.ts (100%)
rename services/content-watcher/apps/{api => worker}/src/blockchain/extrinsic.ts (98%)
create mode 100644 services/content-watcher/apps/worker/src/interfaces/publisher-job.interface.ts
create mode 100644 services/content-watcher/apps/worker/src/publisher/ipfs.publisher.spec.ts
create mode 100644 services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
create mode 100644 services/content-watcher/apps/worker/src/publisher/publisher.module.ts
create mode 100644 services/content-watcher/apps/worker/src/publisher/publishing.service.ts
create mode 100644 services/content-watcher/libs/common/src/constants.ts
diff --git a/services/content-watcher/apps/api/src/api.module.ts b/services/content-watcher/apps/api/src/api.module.ts
index d7da5930..94100d93 100644
--- a/services/content-watcher/apps/api/src/api.module.ts
+++ b/services/content-watcher/apps/api/src/api.module.ts
@@ -7,7 +7,6 @@ import { ApiController } from './api.controller';
import { ConfigService } from './config/config.service';
import { ConfigModule } from './config/config.module';
import { DevelopmentController } from './development.controller';
-import { BlockchainModule } from './blockchain/blockchain.module';
@Module({
imports: [
@@ -42,7 +41,6 @@ import { BlockchainModule } from './blockchain/blockchain.module';
ignoreErrors: false,
}),
ScheduleModule.forRoot(),
- BlockchainModule,
],
providers: [ConfigService],
controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ApiController] : [ApiController],
diff --git a/services/content-watcher/apps/api/src/blockchain/blockchain-constants.ts b/services/content-watcher/apps/worker/src/blockchain/blockchain-constants.ts
similarity index 100%
rename from services/content-watcher/apps/api/src/blockchain/blockchain-constants.ts
rename to services/content-watcher/apps/worker/src/blockchain/blockchain-constants.ts
diff --git a/services/content-watcher/apps/api/src/blockchain/blockchain.module.ts b/services/content-watcher/apps/worker/src/blockchain/blockchain.module.ts
similarity index 80%
rename from services/content-watcher/apps/api/src/blockchain/blockchain.module.ts
rename to services/content-watcher/apps/worker/src/blockchain/blockchain.module.ts
index facacf9c..0205f784 100644
--- a/services/content-watcher/apps/api/src/blockchain/blockchain.module.ts
+++ b/services/content-watcher/apps/worker/src/blockchain/blockchain.module.ts
@@ -4,7 +4,7 @@ https://docs.nestjs.com/modules
import { Module } from '@nestjs/common';
import { BlockchainService } from './blockchain.service';
-import { ConfigModule } from '../config/config.module';
+import { ConfigModule } from '../../../api/src/config/config.module';
@Module({
imports: [ConfigModule],
diff --git a/services/content-watcher/apps/worker/src/blockchain/blockchain.service.spec.ts b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.spec.ts
new file mode 100644
index 00000000..1a172bf9
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.spec.ts
@@ -0,0 +1,18 @@
+import { describe, it, beforeEach } from '@jest/globals';
+import { BlockchainService } from './blockchain.service';
+
+describe('BlockchainService', () => {
+ let blockchainService: BlockchainService;
+
+ beforeEach(async () => {});
+
+ describe('createExtrinsicCall', () => {
+ it('should return an extrinsic call', async () => {
+ const pallet = 'messages';
+ const extrinsic = 'addIpfsMessage';
+ const schemaId = 1;
+ const cid = 'QmRgJZmR6Z6yB5k9aLXjzJ6jG8L6tq4v4J9zQfDz7p3J9v';
+ const payloadLength = 100;
+ });
+ });
+});
diff --git a/services/content-watcher/apps/api/src/blockchain/blockchain.service.ts b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
similarity index 96%
rename from services/content-watcher/apps/api/src/blockchain/blockchain.service.ts
rename to services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
index fae47d1c..3cdd832d 100644
--- a/services/content-watcher/apps/api/src/blockchain/blockchain.service.ts
+++ b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
@@ -9,7 +9,7 @@ import { SubmittableExtrinsic } from '@polkadot/api/types';
import { AnyNumber, ISubmittableResult } from '@polkadot/types/types';
import { u32, Option, u128 } from '@polkadot/types';
import { PalletCapacityCapacityDetails, PalletCapacityEpochInfo } from '@polkadot/types/lookup';
-import { ConfigService } from '../config/config.service';
+import { ConfigService } from '../../../api/src/config/config.service';
import { Extrinsic } from './extrinsic';
@Injectable()
@@ -135,4 +135,8 @@ export class BlockchainService implements OnApplicationBootstrap, OnApplicationS
const epochLength: u32 = await this.query('capacity', 'epochLength');
return typeof epochLength === 'number' ? epochLength : epochLength.toNumber();
}
+
+ public async capacityBatchLimit(): Promise {
+ return this.api.consts.frequencyTxPayment.maximumCapacityBatchLength.toNumber();
+ }
}
diff --git a/services/content-watcher/apps/api/src/blockchain/create-keys.ts b/services/content-watcher/apps/worker/src/blockchain/create-keys.ts
similarity index 100%
rename from services/content-watcher/apps/api/src/blockchain/create-keys.ts
rename to services/content-watcher/apps/worker/src/blockchain/create-keys.ts
diff --git a/services/content-watcher/apps/api/src/blockchain/event-error.ts b/services/content-watcher/apps/worker/src/blockchain/event-error.ts
similarity index 100%
rename from services/content-watcher/apps/api/src/blockchain/event-error.ts
rename to services/content-watcher/apps/worker/src/blockchain/event-error.ts
diff --git a/services/content-watcher/apps/api/src/blockchain/extrinsic.ts b/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
similarity index 98%
rename from services/content-watcher/apps/api/src/blockchain/extrinsic.ts
rename to services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
index cf704912..a435e0ab 100644
--- a/services/content-watcher/apps/api/src/blockchain/extrinsic.ts
+++ b/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
@@ -31,7 +31,7 @@ import { IsEvent } from '@polkadot/types/metadata/decorate/types';
import { Codec, ISubmittableResult, AnyTuple } from '@polkadot/types/types';
import { filter, firstValueFrom, map, pipe, tap } from 'rxjs';
import { KeyringPair } from '@polkadot/keyring/types';
-import { ConfigService } from '../config/config.service';
+import { ConfigService } from '../../../api/src/config/config.service';
import { EventError } from './event-error';
export type EventMap = { [key: string]: Event };
diff --git a/services/content-watcher/apps/worker/src/interfaces/publisher-job.interface.ts b/services/content-watcher/apps/worker/src/interfaces/publisher-job.interface.ts
new file mode 100644
index 00000000..21a00f82
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/interfaces/publisher-job.interface.ts
@@ -0,0 +1,10 @@
+export interface IPFSJobData {
+ cid: string;
+ payloadLength: number;
+}
+
+export interface IPublisherJob {
+ id: string;
+ schemaId: number;
+ data: IPFSJobData;
+}
diff --git a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.spec.ts b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.spec.ts
new file mode 100644
index 00000000..7cbcf65c
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.spec.ts
@@ -0,0 +1,30 @@
+// test file for ipfs publisher
+import { describe, it, beforeEach } from '@jest/globals';
+import { IPFSPublisher } from './ipfs.publisher';
+
+describe('IPFSPublisher', () => {
+ let ipfsPublisher: IPFSPublisher;
+
+ beforeEach(async () => {});
+
+ describe('publish', () => {
+ it('should return capacity used per epoch', async () => {
+ const messages = [
+ {
+ schemaId: 1,
+ data: {
+ cid: 'QmRgJZmR6Z6yB5k9aLXjzJ6jG8L6tq4v4J9zQfDz7p3J9v',
+ payloadLength: 100,
+ },
+ },
+ {
+ schemaId: 1,
+ data: {
+ cid: 'QmRgJZmR6Z6yB5k9aLXjzJ6jG8L6tq4v4J9zQfDz7p3J9v',
+ payloadLength: 100,
+ },
+ },
+ ];
+ });
+ });
+});
diff --git a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
new file mode 100644
index 00000000..726cd033
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
@@ -0,0 +1,86 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { KeyringPair } from '@polkadot/keyring/types';
+import { ISubmittableResult } from '@polkadot/types/types';
+import { SubmittableExtrinsic } from '@polkadot/api-base/types';
+import { BlockchainService } from '../blockchain/blockchain.service';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IPublisherJob } from '../interfaces/publisher-job.interface';
+import { createKeys } from '../blockchain/create-keys';
+
+@Injectable()
+export class IPFSPublisher {
+ private logger: Logger;
+
+ constructor(private configService: ConfigService, private blockchainService: BlockchainService, private eventEmitter: EventEmitter2) {
+ this.logger = new Logger(IPFSPublisher.name);
+ }
+
+ public async publish(messages: IPublisherJob[]): Promise<{ [key: string]: bigint }> {
+ const providerKeys = createKeys(this.configService.getProviderAccountSeedPhrase());
+
+ let batch: SubmittableExtrinsic<'rxjs', ISubmittableResult>[] = [];
+ const batches: SubmittableExtrinsic<'rxjs', ISubmittableResult>[][] = [];
+ const allowedBatchLen = await this.blockchainService.capacityBatchLimit();
+ messages.forEach((message) => {
+ batch.push(this.blockchainService.createExtrinsicCall({ pallet: 'messages', extrinsic: 'addIpfsMessage' }, message.schemaId, message.data.cid, message.data.payloadLength));
+
+ if (batch.length === allowedBatchLen) {
+ batches.push(batch);
+ batch = [];
+ }
+ });
+
+ if (batch.length > 0) {
+ batches.push(batch);
+ }
+ return this.sendAndProcessChainEvents(providerKeys, batches);
+ }
+
+ async sendAndProcessChainEvents(providerKeys: KeyringPair, batchesMap: SubmittableExtrinsic<'rxjs', ISubmittableResult>[][]): Promise<{ [key: string]: bigint }> {
+ try {
+ // iterate over batches and send them to the chain returning the capacity withdrawn
+ const batchPromises: Promise<{ [key: string]: bigint }>[] = [];
+
+ batchesMap.forEach(async (batch) => {
+ batchPromises.push(this.processSingleBatch(providerKeys, batch));
+ });
+
+ const totalCapUsedPerEpoch = await Promise.all(batchPromises);
+ const totalCapacityUsed = totalCapUsedPerEpoch.reduce((acc, curr) => {
+ const epoch = Object.keys(curr)[0];
+ if (acc[epoch]) {
+ acc[epoch] += curr[epoch];
+ }
+ acc[epoch] = curr[epoch];
+ return acc;
+ }, {} as { [key: string]: bigint });
+
+ this.logger.debug(`Total capacity used: ${JSON.stringify(totalCapacityUsed)}`);
+ return totalCapacityUsed;
+ } catch (e) {
+ this.logger.error(`Error processing batches: ${e}`);
+ throw e;
+ }
+ }
+
+ async processSingleBatch(providerKeys: KeyringPair, batch: SubmittableExtrinsic<'rxjs', ISubmittableResult>[]): Promise<{ [key: string]: bigint }> {
+ this.logger.debug(`Submitting batch of size ${batch.length}`);
+ try {
+ const currrentEpoch = await this.blockchainService.getCurrentCapacityEpoch();
+ const [event, eventMap] = await this.blockchainService
+ .createExtrinsic({ pallet: 'frequencyTxPayment', extrinsic: 'payWithCapacityBatchAll' }, { eventPallet: 'utility', event: 'BatchCompleted' }, providerKeys, batch)
+ .signAndSend();
+ if (!event || !this.blockchainService.api.events.utility.BatchCompleted.is(event)) {
+ // if we dont get any events, covering any unexpected connection errors
+ throw new Error(`No events were found for batch`);
+ }
+ const capacityWithDrawn = BigInt(eventMap['capacity.CapacityWithdrawn'].data[1].toString());
+ this.logger.debug(`Batch processed, capacity withdrawn: ${capacityWithDrawn}`);
+ return { [currrentEpoch.toString()]: capacityWithDrawn };
+ } catch (e) {
+ this.logger.error(`Error processing batch: ${e}`);
+ throw e;
+ }
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/publisher/publisher.module.ts b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
new file mode 100644
index 00000000..de3c7fde
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
@@ -0,0 +1,69 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { BullModule } from '@nestjs/bullmq';
+import { Module } from '@nestjs/common';
+import { EventEmitterModule } from '@nestjs/event-emitter';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { PublishingService } from './publishing.service';
+import { ConfigModule } from '../../../api/src/config/config.module';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { BlockchainModule } from '../blockchain/blockchain.module';
+import { IPFSPublisher } from './ipfs.publisher';
+
+@Module({
+ imports: [
+ BlockchainModule,
+ ConfigModule,
+ EventEmitterModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ BullModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => {
+ // Note: BullMQ doesn't honor a URL for the Redis connection, and
+ // JS URL doesn't parse 'redis://' as a valid protocol, so we fool
+ // it by changing the URL to use 'http://' in order to parse out
+ // the host, port, username, password, etc.
+ // We could pass REDIS_HOST, REDIS_PORT, etc, in the environment, but
+ // trying to keep the # of environment variables from proliferating
+ const url = new URL(configService.redisUrl.toString().replace(/^redis[s]*/, 'http'));
+ const { hostname, port, username, password, pathname } = url;
+ return {
+ connection: {
+ host: hostname || undefined,
+ port: port ? Number(port) : undefined,
+ username: username || undefined,
+ password: password || undefined,
+ db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
+ },
+ };
+ },
+ inject: [ConfigService],
+ }),
+ BullModule.registerQueue({
+ name: 'publishQueue',
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: true,
+ removeOnFail: false,
+ },
+ }),
+ ],
+ controllers: [],
+ providers: [PublishingService, IPFSPublisher],
+ exports: [BullModule, PublishingService, IPFSPublisher],
+})
+export class PublisherModule {}
diff --git a/services/content-watcher/apps/worker/src/publisher/publishing.service.ts b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
new file mode 100644
index 00000000..88bd6f47
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
@@ -0,0 +1,161 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Processor, WorkerHost, OnWorkerEvent, InjectQueue } from '@nestjs/bullmq';
+import { Injectable, Logger, OnApplicationBootstrap, OnModuleDestroy } from '@nestjs/common';
+import { Job, Queue } from 'bullmq';
+import Redis from 'ioredis';
+import { SchedulerRegistry } from '@nestjs/schedule';
+import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
+import { MILLISECONDS_PER_SECOND } from 'time-constants';
+import { BlockchainService } from '../blockchain/blockchain.service';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IPublisherJob } from '../interfaces/publisher-job.interface';
+import { IPFSPublisher } from './ipfs.publisher';
+import { CAPACITY_EPOCH_TIMEOUT_NAME, SECONDS_PER_BLOCK } from '../../../../libs/common/src/constants';
+
+@Injectable()
+@Processor('publishQueue', {
+ concurrency: 2,
+})
+export class PublishingService extends WorkerHost implements OnApplicationBootstrap, OnModuleDestroy {
+ private logger: Logger;
+
+ private capacityExhausted = false;
+
+ constructor(
+ @InjectRedis() private cacheManager: Redis,
+ @InjectQueue('publishQueue') private publishQueue: Queue,
+ private blockchainService: BlockchainService,
+ private configService: ConfigService,
+ private ipfsPublisher: IPFSPublisher,
+ private schedulerRegistry: SchedulerRegistry,
+ private eventEmitter: EventEmitter2,
+ ) {
+ super();
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ public async onApplicationBootstrap() {
+ await this.checkCapacity();
+ }
+
+ public onModuleDestroy() {
+ try {
+ this.schedulerRegistry.deleteTimeout(CAPACITY_EPOCH_TIMEOUT_NAME);
+ } catch (e) {
+ // 💀 //
+ }
+ }
+
+ async process(job: Job): Promise {
+ this.logger.log(`Processing job ${job.id} of type ${job.name}`);
+ try {
+ // TODO: this is only performing one message per batch, figure out how to batch multiple messages
+ const totalCapacityUsed = await this.ipfsPublisher.publish([job.data]);
+ await this.setEpochCapacity(totalCapacityUsed);
+
+ this.logger.verbose(`Successfully completed job ${job.id}`);
+ return { success: true };
+ } catch (e) {
+ this.logger.error(`Job ${job.id} failed (attempts=${job.attemptsMade})`);
+ if (e instanceof Error && e.message.includes('Inability to pay some fees')) {
+ this.eventEmitter.emit('capacity.exhausted');
+ // TODO: revisit this logic
+ }
+ throw e;
+ } finally {
+ await this.checkCapacity();
+ }
+ }
+
+ private async setEpochCapacity(totalCapacityUsed: { [key: string]: bigint }): Promise {
+ Object.entries(totalCapacityUsed).forEach(async ([epoch, capacityUsed]) => {
+ const epochCapacityKey = `epochCapacity:${epoch}`;
+
+ try {
+ const epochCapacity = BigInt((await this.cacheManager.get(epochCapacityKey)) ?? 0);
+ const newEpochCapacity = epochCapacity + capacityUsed;
+
+ const epochDurationBlocks = await this.blockchainService.getCurrentEpochLength();
+ const epochDuration = epochDurationBlocks * SECONDS_PER_BLOCK * MILLISECONDS_PER_SECOND;
+
+ await this.cacheManager.setex(epochCapacityKey, epochDuration, newEpochCapacity.toString());
+ } catch (error) {
+ this.logger.error(`Error setting epoch capacity: ${error}`);
+
+ throw error;
+ }
+ });
+ }
+
+ private async checkCapacity(): Promise {
+ const capacityLimit = this.configService.getCapacityLimit();
+ const capacity = await this.blockchainService.capacityInfo(this.configService.getProviderId());
+ const { remainingCapacity } = capacity;
+ const { currentEpoch } = capacity;
+ const epochCapacityKey = `epochCapacity:${currentEpoch}`;
+ const epochUsedCapacity = BigInt((await this.cacheManager.get(epochCapacityKey)) ?? 0); // Fetch capacity used by the service
+ let outOfCapacity = remainingCapacity <= 0n;
+
+ if (!outOfCapacity) {
+ this.logger.debug(`Capacity remaining: ${remainingCapacity}`);
+ if (capacityLimit.type === 'percentage') {
+ const capacityLimitPercentage = BigInt(capacityLimit.value);
+ const capacityLimitThreshold = (capacity.totalCapacityIssued * capacityLimitPercentage) / 100n;
+ this.logger.debug(`Capacity limit threshold: ${capacityLimitThreshold}`);
+ if (epochUsedCapacity >= capacityLimitThreshold) {
+ outOfCapacity = true;
+ this.logger.warn(`Capacity threshold reached: used ${epochUsedCapacity} of ${capacityLimitThreshold}`);
+ }
+ } else if (epochUsedCapacity >= capacityLimit.value) {
+ outOfCapacity = true;
+ this.logger.warn(`Capacity threshold reached: used ${epochUsedCapacity} of ${capacityLimit.value}`);
+ }
+ }
+
+ if (outOfCapacity) {
+ await this.eventEmitter.emitAsync('capacity.exhausted');
+ } else {
+ await this.eventEmitter.emitAsync('capacity.refilled');
+ }
+ }
+
+ @OnEvent('capacity.exhausted', { async: true, promisify: true })
+ private async handleCapacityExhausted() {
+ this.logger.debug('Received capacity.exhausted event');
+ this.capacityExhausted = true;
+ await this.publishQueue.pause();
+ const capacityLimit = this.configService.getCapacityLimit();
+ const capacity = await this.blockchainService.capacityInfo(this.configService.getProviderId());
+
+ this.logger.debug(`
+ Capacity limit: ${JSON.stringify(capacityLimit)}
+ Remaining Capacity: ${JSON.stringify(capacity.remainingCapacity.toString())})}`);
+
+ const blocksRemaining = capacity.nextEpochStart - capacity.currentBlockNumber;
+ try {
+ this.schedulerRegistry.addTimeout(
+ CAPACITY_EPOCH_TIMEOUT_NAME,
+ setTimeout(() => this.checkCapacity(), blocksRemaining * SECONDS_PER_BLOCK * MILLISECONDS_PER_SECOND),
+ );
+ } catch (err) {
+ // ignore duplicate timeout
+ }
+ }
+
+ @OnEvent('capacity.refilled', { async: true, promisify: true })
+ private async handleCapacityRefilled() {
+ this.logger.debug('Received capacity.refilled event');
+ this.capacityExhausted = false;
+ try {
+ this.schedulerRegistry.deleteTimeout(CAPACITY_EPOCH_TIMEOUT_NAME);
+ } catch (err) {
+ // ignore
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ onCompleted() {
+ // do some stuff
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/worker.module.ts b/services/content-watcher/apps/worker/src/worker.module.ts
index 1a33a57e..010cd3c6 100644
--- a/services/content-watcher/apps/worker/src/worker.module.ts
+++ b/services/content-watcher/apps/worker/src/worker.module.ts
@@ -1,22 +1,51 @@
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
+import { ScheduleModule } from '@nestjs/schedule';
+import { EventEmitterModule } from '@nestjs/event-emitter';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { PublishingService } from './publisher/publishing.service';
+import { PublisherModule } from './publisher/publisher.module';
import { WorkerService } from './worker.service';
-import { ExampleConsumer } from './consumer';
-import { ExampleQueueEvents } from './event.listener';
+import { ConfigService } from '../../api/src/config/config.service';
+import { BlockchainModule } from './blockchain/blockchain.module';
+import { ConfigModule } from '../../api/src/config/config.module';
@Module({
imports: [
- BullModule.forRoot({
- connection: {
- host: 'localhost',
- port: 6379,
- enableOfflineQueue: false,
+ BullModule,
+ ConfigModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
},
+ true, // isGlobal
+ ),
+ EventEmitterModule.forRoot({
+ // Use this instance throughout the application
+ global: true,
+ // set this to `true` to use wildcards
+ wildcard: false,
+ // the delimiter used to segment namespaces
+ delimiter: '.',
+ // set this to `true` if you want to emit the newListener event
+ newListener: false,
+ // set this to `true` if you want to emit the removeListener event
+ removeListener: false,
+ // the maximum amount of listeners that can be assigned to an event
+ maxListeners: 10,
+ // show event name in memory leak message when more than maximum amount of listeners is assigned
+ verboseMemoryLeak: false,
+ // disable throwing uncaughtException if an error event is emitted and it has no listeners
+ ignoreErrors: false,
}),
- BullModule.registerQueue({
- name: 'testQueue',
- }),
+ ScheduleModule.forRoot(),
+ PublisherModule,
+ BlockchainModule,
],
- providers: [WorkerService, ExampleConsumer, ExampleQueueEvents],
+ providers: [ConfigService, WorkerService, PublishingService],
})
export class WorkerModule {}
diff --git a/services/content-watcher/libs/common/src/constants.ts b/services/content-watcher/libs/common/src/constants.ts
new file mode 100644
index 00000000..a7df8f39
--- /dev/null
+++ b/services/content-watcher/libs/common/src/constants.ts
@@ -0,0 +1,2 @@
+export const SECONDS_PER_BLOCK = 12;
+export const CAPACITY_EPOCH_TIMEOUT_NAME = 'capacity-epoch-timeout';
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index f26ec156..ef07ccf5 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -10,9 +10,11 @@
"license": "Apache-2.0",
"dependencies": {
"@frequency-chain/api-augment": "1.7.0",
+ "@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
"@nestjs/bullmq": "^10.0.0",
+ "@nestjs/cli": "^10.1.14",
"@nestjs/common": "^9.4.0",
"@nestjs/config": "^2.3.1",
"@nestjs/core": "^9.4.0",
@@ -40,8 +42,6 @@
"time-constants": "^1.0.3"
},
"devDependencies": {
- "@jest/globals": "^29.5.0",
- "@nestjs/cli": "^10.1.14",
"@polkadot/typegen": "10.9.1",
"@types/jest": "^29.5.2",
"@types/time-constants": "^1.0.0",
@@ -76,7 +76,6 @@
},
"node_modules/@ampproject/remapping": {
"version": "2.2.1",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
@@ -90,7 +89,6 @@
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.0.tgz",
"integrity": "sha512-l1k6Rqm3YM16BEn3CWyQKrk9xfu+2ux7Bw3oS+h1TO4/RoxO2PgHj8LLRh/WNrYVarhaqO7QZ5ePBkXNMkzJ1g==",
- "dev": true,
"dependencies": {
"ajv": "8.12.0",
"ajv-formats": "2.1.1",
@@ -116,7 +114,6 @@
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -131,14 +128,12 @@
"node_modules/@angular-devkit/core/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/@angular-devkit/core/node_modules/source-map": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
- "dev": true,
"engines": {
"node": ">= 8"
}
@@ -147,7 +142,6 @@
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.0.tgz",
"integrity": "sha512-QMDJXPE0+YQJ9Ap3MMzb0v7rx6ZbBEokmHgpdIjN3eILYmbAdsSGE8HTV8NjS9nKmcyE9OGzFCMb7PFrDTlTAw==",
- "dev": true,
"dependencies": {
"@angular-devkit/core": "16.2.0",
"jsonc-parser": "3.2.0",
@@ -165,7 +159,6 @@
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.2.0.tgz",
"integrity": "sha512-f3HjrDvSrRMvESogLsqsZXsEg//trIBySCHRXCglPrWLVdBbIRctGOhXqZoclRxXimIKUx14zLsOWzDwZG8+HQ==",
- "dev": true,
"dependencies": {
"@angular-devkit/core": "16.2.0",
"@angular-devkit/schematics": "16.2.0",
@@ -187,7 +180,6 @@
"version": "8.2.4",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
"integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
- "dev": true,
"dependencies": {
"ansi-escapes": "^4.2.1",
"chalk": "^4.1.1",
@@ -211,7 +203,6 @@
},
"node_modules/@babel/code-frame": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.22.5"
@@ -222,7 +213,6 @@
},
"node_modules/@babel/compat-data": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -230,7 +220,6 @@
},
"node_modules/@babel/core": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -259,12 +248,10 @@
},
"node_modules/@babel/core/node_modules/convert-source-map": {
"version": "1.9.0",
- "dev": true,
"license": "MIT"
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -272,7 +259,6 @@
},
"node_modules/@babel/generator": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.22.5",
@@ -286,7 +272,6 @@
},
"node_modules/@babel/generator/node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -294,12 +279,10 @@
},
"node_modules/@babel/generator/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
- "dev": true,
"license": "MIT"
},
"node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
@@ -308,7 +291,6 @@
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.5",
@@ -326,7 +308,6 @@
},
"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
"version": "5.1.1",
- "dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
@@ -334,7 +315,6 @@
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -342,12 +322,10 @@
},
"node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
"version": "3.1.1",
- "dev": true,
"license": "ISC"
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -355,7 +333,6 @@
},
"node_modules/@babel/helper-function-name": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.22.5",
@@ -367,7 +344,6 @@
},
"node_modules/@babel/helper-hoist-variables": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.22.5"
@@ -378,7 +354,6 @@
},
"node_modules/@babel/helper-module-imports": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.22.5"
@@ -389,7 +364,6 @@
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.5",
@@ -407,7 +381,6 @@
},
"node_modules/@babel/helper-plugin-utils": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -415,7 +388,6 @@
},
"node_modules/@babel/helper-simple-access": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.22.5"
@@ -426,7 +398,6 @@
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.22.5"
@@ -437,7 +408,6 @@
},
"node_modules/@babel/helper-string-parser": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -445,7 +415,6 @@
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -453,7 +422,6 @@
},
"node_modules/@babel/helper-validator-option": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -461,7 +429,6 @@
},
"node_modules/@babel/helpers": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.22.5",
@@ -474,7 +441,6 @@
},
"node_modules/@babel/highlight": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.5",
@@ -487,7 +453,6 @@
},
"node_modules/@babel/highlight/node_modules/ansi-styles": {
"version": "3.2.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^1.9.0"
@@ -498,7 +463,6 @@
},
"node_modules/@babel/highlight/node_modules/chalk": {
"version": "2.4.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
@@ -511,7 +475,6 @@
},
"node_modules/@babel/highlight/node_modules/color-convert": {
"version": "1.9.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-name": "1.1.3"
@@ -519,12 +482,10 @@
},
"node_modules/@babel/highlight/node_modules/color-name": {
"version": "1.1.3",
- "dev": true,
"license": "MIT"
},
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
@@ -532,7 +493,6 @@
},
"node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -540,7 +500,6 @@
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
@@ -551,7 +510,6 @@
},
"node_modules/@babel/parser": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"bin": {
"parser": "bin/babel-parser.js"
@@ -562,7 +520,6 @@
},
"node_modules/@babel/plugin-syntax-async-generators": {
"version": "7.8.4",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -573,7 +530,6 @@
},
"node_modules/@babel/plugin-syntax-bigint": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -584,7 +540,6 @@
},
"node_modules/@babel/plugin-syntax-class-properties": {
"version": "7.12.13",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13"
@@ -595,7 +550,6 @@
},
"node_modules/@babel/plugin-syntax-import-meta": {
"version": "7.10.4",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -606,7 +560,6 @@
},
"node_modules/@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -617,7 +570,6 @@
},
"node_modules/@babel/plugin-syntax-jsx": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -631,7 +583,6 @@
},
"node_modules/@babel/plugin-syntax-logical-assignment-operators": {
"version": "7.10.4",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -642,7 +593,6 @@
},
"node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -653,7 +603,6 @@
},
"node_modules/@babel/plugin-syntax-numeric-separator": {
"version": "7.10.4",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -664,7 +613,6 @@
},
"node_modules/@babel/plugin-syntax-object-rest-spread": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -675,7 +623,6 @@
},
"node_modules/@babel/plugin-syntax-optional-catch-binding": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -686,7 +633,6 @@
},
"node_modules/@babel/plugin-syntax-optional-chaining": {
"version": "7.8.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -697,7 +643,6 @@
},
"node_modules/@babel/plugin-syntax-top-level-await": {
"version": "7.14.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -711,7 +656,6 @@
},
"node_modules/@babel/plugin-syntax-typescript": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -736,7 +680,6 @@
},
"node_modules/@babel/template": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.22.5",
@@ -749,7 +692,6 @@
},
"node_modules/@babel/traverse": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.22.5",
@@ -769,7 +711,6 @@
},
"node_modules/@babel/traverse/node_modules/globals": {
"version": "11.12.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -777,7 +718,6 @@
},
"node_modules/@babel/types": {
"version": "7.22.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.22.5",
@@ -798,7 +738,6 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
"integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
- "dev": true,
"optional": true,
"engines": {
"node": ">=0.1.90"
@@ -923,7 +862,6 @@
},
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
- "dev": true,
"license": "ISC",
"dependencies": {
"camelcase": "^5.3.1",
@@ -938,7 +876,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
"version": "1.0.10",
- "dev": true,
"license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
@@ -946,7 +883,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
"version": "4.1.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
@@ -958,7 +894,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
"version": "3.14.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
@@ -970,7 +905,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
"version": "5.0.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
@@ -981,7 +915,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
"version": "2.3.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
@@ -995,7 +928,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
"version": "4.1.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
@@ -1006,7 +938,6 @@
},
"node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
"version": "5.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -1014,7 +945,6 @@
},
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -1086,7 +1016,6 @@
},
"node_modules/@jest/environment": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/fake-timers": "^29.5.0",
@@ -1100,7 +1029,6 @@
},
"node_modules/@jest/expect": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"expect": "^29.5.0",
@@ -1112,7 +1040,6 @@
},
"node_modules/@jest/expect-utils": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"jest-get-type": "^29.4.3"
@@ -1123,7 +1050,6 @@
},
"node_modules/@jest/fake-timers": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/types": "^29.5.0",
@@ -1139,7 +1065,6 @@
},
"node_modules/@jest/globals": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/environment": "^29.5.0",
@@ -1221,7 +1146,6 @@
},
"node_modules/@jest/schemas": {
"version": "29.4.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@sinclair/typebox": "^0.25.16"
@@ -1301,7 +1225,6 @@
},
"node_modules/@jest/transform": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
@@ -1326,7 +1249,6 @@
},
"node_modules/@jest/transform/node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1334,12 +1256,10 @@
},
"node_modules/@jest/transform/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
- "dev": true,
"license": "MIT"
},
"node_modules/@jest/transform/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
@@ -1348,7 +1268,6 @@
},
"node_modules/@jest/types": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/schemas": "^29.4.3",
@@ -1364,7 +1283,6 @@
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
@@ -1377,7 +1295,6 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.1",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1385,7 +1302,6 @@
},
"node_modules/@jridgewell/set-array": {
"version": "1.1.2",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1395,7 +1311,6 @@
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
- "dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -1403,12 +1318,10 @@
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
@@ -1484,7 +1397,6 @@
"version": "10.1.14",
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.1.14.tgz",
"integrity": "sha512-oxfoebzrq6g+MKc6FRx2O8D86Vk0ViEmlP4B1E3dzwC3X5yjxlA1IDulLrVz3VIpGjuyuXmrQjjd8l0NUVZiKg==",
- "dev": true,
"dependencies": {
"@angular-devkit/core": "16.2.0",
"@angular-devkit/schematics": "16.2.0",
@@ -1532,7 +1444,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -1541,7 +1452,6 @@
"version": "9.3.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
"integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
- "dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"minimatch": "^8.0.2",
@@ -1559,7 +1469,6 @@
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
"integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
- "dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -1574,7 +1483,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz",
"integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
- "dev": true,
"dependencies": {
"glob": "^9.2.0"
},
@@ -1747,7 +1655,6 @@
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.0.2.tgz",
"integrity": "sha512-DaZZjymYoIfRqC5W62lnYXIIods1PDY6CGc8+IpRwyinzffjKxZ3DF3exu+mdyvllzkXo9DTXkoX4zOPSJHCkw==",
- "dev": true,
"dependencies": {
"@angular-devkit/core": "16.1.8",
"@angular-devkit/schematics": "16.1.8",
@@ -1763,7 +1670,6 @@
"version": "16.1.8",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.8.tgz",
"integrity": "sha512-dSRD/+bGanArIXkj+kaU1kDFleZeQMzmBiOXX+pK0Ah9/0Yn1VmY3RZh1zcX9vgIQXV+t7UPrTpOjaERMUtVGw==",
- "dev": true,
"dependencies": {
"ajv": "8.12.0",
"ajv-formats": "2.1.1",
@@ -1789,7 +1695,6 @@
"version": "16.1.8",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.8.tgz",
"integrity": "sha512-6LyzMdFJs337RTxxkI2U1Ndw0CW5mMX/aXWl8d7cW2odiSrAg8IdlMqpc+AM8+CPfsB0FtS1aWkEZqJLT0jHOg==",
- "dev": true,
"dependencies": {
"@angular-devkit/core": "16.1.8",
"jsonc-parser": "3.2.0",
@@ -1807,7 +1712,6 @@
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -1822,14 +1726,12 @@
"node_modules/@nestjs/schematics/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/@nestjs/schematics/node_modules/magic-string": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
"integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
- "dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.13"
},
@@ -1841,7 +1743,6 @@
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
- "dev": true,
"engines": {
"node": ">= 8"
}
@@ -2616,7 +2517,6 @@
},
"node_modules/@sinclair/typebox": {
"version": "0.25.24",
- "dev": true,
"license": "MIT"
},
"node_modules/@sindresorhus/is": {
@@ -2632,7 +2532,6 @@
},
"node_modules/@sinonjs/commons": {
"version": "3.0.0",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"type-detect": "4.0.8"
@@ -2640,7 +2539,6 @@
},
"node_modules/@sinonjs/fake-timers": {
"version": "10.1.0",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@sinonjs/commons": "^3.0.0"
@@ -2740,7 +2638,6 @@
},
"node_modules/@types/babel__traverse": {
"version": "7.20.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.20.7"
@@ -2774,7 +2671,6 @@
"version": "8.44.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz",
"integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==",
- "dev": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -2784,7 +2680,6 @@
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
"integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
- "dev": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
@@ -2793,8 +2688,7 @@
"node_modules/@types/estree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
- "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
- "dev": true
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA=="
},
"node_modules/@types/express": {
"version": "4.17.17",
@@ -2820,7 +2714,6 @@
},
"node_modules/@types/graceful-fs": {
"version": "4.1.6",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
@@ -2838,12 +2731,10 @@
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/istanbul-lib-report": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-coverage": "*"
@@ -2851,7 +2742,6 @@
},
"node_modules/@types/istanbul-reports": {
"version": "3.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-report": "*"
@@ -2868,7 +2758,6 @@
},
"node_modules/@types/json-schema": {
"version": "7.0.12",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/json5": {
@@ -2896,12 +2785,10 @@
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "dev": true
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"node_modules/@types/prettier": {
"version": "2.7.3",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/qs": {
@@ -2941,7 +2828,6 @@
},
"node_modules/@types/stack-utils": {
"version": "2.0.1",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/strip-bom": {
@@ -2970,7 +2856,6 @@
},
"node_modules/@types/yargs": {
"version": "17.0.24",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
@@ -2978,7 +2863,6 @@
},
"node_modules/@types/yargs-parser": {
"version": "21.0.0",
- "dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
@@ -3400,7 +3284,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
"integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
- "dev": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6"
@@ -3409,26 +3292,22 @@
"node_modules/@webassemblyjs/floating-point-hex-parser": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
- "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
- "dev": true
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw=="
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
- "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
- "dev": true
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
- "dev": true
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA=="
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
"integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
- "dev": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.11.6",
"@webassemblyjs/helper-api-error": "1.11.6",
@@ -3438,14 +3317,12 @@
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
- "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
- "dev": true
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
"integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -3457,7 +3334,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
"integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
- "dev": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@@ -3466,7 +3342,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
"integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
- "dev": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@@ -3474,14 +3349,12 @@
"node_modules/@webassemblyjs/utf8": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
- "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
- "dev": true
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
"integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -3497,7 +3370,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
"integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
@@ -3510,7 +3382,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
"integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -3522,7 +3393,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
"integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-api-error": "1.11.6",
@@ -3536,7 +3406,6 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
"integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
- "dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@xtuc/long": "4.2.2"
@@ -3545,14 +3414,12 @@
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
- "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
- "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
},
"node_modules/accepts": {
"version": "1.3.8",
@@ -3567,7 +3434,6 @@
},
"node_modules/acorn": {
"version": "8.8.2",
- "devOptional": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3580,7 +3446,6 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
- "dev": true,
"peerDependencies": {
"acorn": "^8"
}
@@ -3603,7 +3468,6 @@
},
"node_modules/ajv": {
"version": "6.12.6",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -3620,7 +3484,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
- "dev": true,
"dependencies": {
"ajv": "^8.0.0"
},
@@ -3637,7 +3500,6 @@
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -3652,14 +3514,12 @@
"node_modules/ajv-formats/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
"peerDependencies": {
"ajv": "^6.9.1"
}
@@ -3668,14 +3528,12 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/ansi-escapes": {
"version": "4.3.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.21.3"
@@ -3689,7 +3547,6 @@
},
"node_modules/ansi-escapes/node_modules/type-fest": {
"version": "0.21.3",
- "dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
@@ -3725,7 +3582,6 @@
},
"node_modules/anymatch": {
"version": "3.1.3",
- "dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@@ -3793,8 +3649,7 @@
"node_modules/array-timsort": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
- "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
- "dev": true
+ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ=="
},
"node_modules/array-union": {
"version": "2.1.0",
@@ -3891,7 +3746,6 @@
},
"node_modules/babel-plugin-istanbul": {
"version": "6.1.1",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
@@ -3921,7 +3775,6 @@
},
"node_modules/babel-preset-current-node-syntax": {
"version": "1.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
@@ -3989,7 +3842,6 @@
},
"node_modules/binary-extensions": {
"version": "2.2.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -3999,7 +3851,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dev": true,
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@ -4010,7 +3861,6 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -4034,7 +3884,6 @@
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -4094,7 +3943,6 @@
},
"node_modules/brace-expansion": {
"version": "1.1.11",
- "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -4103,7 +3951,6 @@
},
"node_modules/braces": {
"version": "3.0.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.0.1"
@@ -4114,7 +3961,6 @@
},
"node_modules/browserslist": {
"version": "4.21.8",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4156,7 +4002,6 @@
},
"node_modules/bser": {
"version": "2.1.1",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"node-int64": "^0.4.0"
@@ -4333,7 +4178,6 @@
},
"node_modules/callsites": {
"version": "3.1.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4341,7 +4185,6 @@
},
"node_modules/camelcase": {
"version": "5.3.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4349,7 +4192,6 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001502",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4392,12 +4234,10 @@
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
- "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
- "dev": true
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"node_modules/chokidar": {
"version": "3.5.3",
- "dev": true,
"funding": [
{
"type": "individual",
@@ -4423,7 +4263,6 @@
},
"node_modules/chokidar/node_modules/glob-parent": {
"version": "5.1.2",
- "dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@@ -4436,14 +4275,12 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
"integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
- "dev": true,
"engines": {
"node": ">=6.0"
}
},
"node_modules/ci-info": {
"version": "3.8.0",
- "dev": true,
"funding": [
{
"type": "github",
@@ -4478,7 +4315,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "dev": true,
"dependencies": {
"restore-cursor": "^3.1.0"
},
@@ -4545,7 +4381,6 @@
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz",
"integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==",
- "dev": true,
"engines": {
"node": ">=6"
},
@@ -4557,7 +4392,6 @@
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
"integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
- "dev": true,
"dependencies": {
"string-width": "^4.2.0"
},
@@ -4572,7 +4406,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
- "dev": true,
"engines": {
"node": ">= 10"
}
@@ -4593,7 +4426,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
- "dev": true,
"engines": {
"node": ">=0.8"
}
@@ -4649,7 +4481,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
"engines": {
"node": ">= 6"
}
@@ -4658,7 +4489,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz",
"integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==",
- "dev": true,
"dependencies": {
"array-timsort": "^1.0.3",
"core-util-is": "^1.0.3",
@@ -4672,7 +4502,6 @@
},
"node_modules/concat-map": {
"version": "0.0.1",
- "dev": true,
"license": "MIT"
},
"node_modules/concat-stream": {
@@ -4716,7 +4545,6 @@
},
"node_modules/convert-source-map": {
"version": "2.0.0",
- "dev": true,
"license": "MIT"
},
"node_modules/cookie": {
@@ -4749,7 +4577,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
- "dev": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@@ -4785,7 +4612,6 @@
},
"node_modules/cross-spawn": {
"version": "7.0.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -4879,7 +4705,6 @@
},
"node_modules/deepmerge": {
"version": "4.3.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -4921,7 +4746,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
- "dev": true,
"dependencies": {
"clone": "^1.0.2"
},
@@ -5011,7 +4835,6 @@
},
"node_modules/diff-sequences": {
"version": "29.4.3",
- "dev": true,
"license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -5070,7 +4893,6 @@
},
"node_modules/electron-to-chromium": {
"version": "1.4.429",
- "dev": true,
"license": "ISC"
},
"node_modules/emittery": {
@@ -5100,7 +4922,6 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
"dependencies": {
"once": "^1.4.0"
}
@@ -5109,7 +4930,6 @@
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
- "dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -5125,7 +4945,6 @@
},
"node_modules/error-ex": {
"version": "1.3.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -5181,8 +5000,7 @@
"node_modules/es-module-lexer": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
- "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
- "dev": true
+ "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA=="
},
"node_modules/es-set-tostringtag": {
"version": "2.0.1",
@@ -5635,7 +5453,6 @@
},
"node_modules/eslint-scope": {
"version": "5.1.1",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
@@ -5722,7 +5539,6 @@
},
"node_modules/esprima": {
"version": "4.0.1",
- "dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -5753,7 +5569,6 @@
},
"node_modules/esrecurse": {
"version": "4.3.0",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
@@ -5764,7 +5579,6 @@
},
"node_modules/esrecurse/node_modules/estraverse": {
"version": "5.3.0",
- "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -5772,7 +5586,6 @@
},
"node_modules/estraverse": {
"version": "4.3.0",
- "dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -5805,7 +5618,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true,
"engines": {
"node": ">=0.8.x"
}
@@ -5842,7 +5654,6 @@
},
"node_modules/expect": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/expect-utils": "^29.5.0",
@@ -5949,7 +5760,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
- "dev": true,
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
@@ -5961,7 +5771,6 @@
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
- "dev": true,
"license": "MIT"
},
"node_modules/fast-diff": {
@@ -5997,7 +5806,6 @@
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
- "dev": true,
"license": "MIT"
},
"node_modules/fast-levenshtein": {
@@ -6019,7 +5827,6 @@
},
"node_modules/fb-watchman": {
"version": "2.0.2",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"bser": "2.1.1"
@@ -6050,7 +5857,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
- "dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.5"
},
@@ -6065,7 +5871,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
"engines": {
"node": ">=0.8.0"
}
@@ -6083,7 +5888,6 @@
},
"node_modules/fill-range": {
"version": "7.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -6181,7 +5985,6 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz",
"integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==",
- "dev": true,
"dependencies": {
"@babel/code-frame": "^7.16.7",
"chalk": "^4.1.2",
@@ -6253,7 +6056,6 @@
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -6266,8 +6068,7 @@
"node_modules/fs-monkey": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz",
- "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==",
- "dev": true
+ "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ=="
},
"node_modules/fs.realpath": {
"version": "1.0.0",
@@ -6313,7 +6114,6 @@
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -6341,7 +6141,6 @@
},
"node_modules/get-package-type": {
"version": "0.1.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.0.0"
@@ -6394,7 +6193,6 @@
},
"node_modules/glob": {
"version": "7.2.3",
- "dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -6425,8 +6223,7 @@
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
- "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"node_modules/globals": {
"version": "13.20.0",
@@ -6512,7 +6309,6 @@
},
"node_modules/graceful-fs": {
"version": "4.2.11",
- "dev": true,
"license": "ISC"
},
"node_modules/grapheme-splitter": {
@@ -6575,7 +6371,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
"integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -6716,7 +6511,6 @@
},
"node_modules/import-fresh": {
"version": "3.3.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -6750,7 +6544,6 @@
},
"node_modules/imurmurhash": {
"version": "0.1.4",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.19"
@@ -6777,7 +6570,6 @@
"version": "8.2.6",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
"integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
- "dev": true,
"dependencies": {
"ansi-escapes": "^4.2.1",
"chalk": "^4.1.1",
@@ -6803,7 +6595,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@@ -6830,7 +6621,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
- "dev": true,
"engines": {
"node": ">= 0.10"
}
@@ -6879,7 +6669,6 @@
},
"node_modules/is-arrayish": {
"version": "0.2.1",
- "dev": true,
"license": "MIT"
},
"node_modules/is-bigint": {
@@ -6895,7 +6684,6 @@
},
"node_modules/is-binary-path": {
"version": "2.1.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
@@ -6932,7 +6720,6 @@
},
"node_modules/is-core-module": {
"version": "2.12.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"has": "^1.0.3"
@@ -6971,7 +6758,6 @@
},
"node_modules/is-extglob": {
"version": "2.1.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -6995,7 +6781,6 @@
},
"node_modules/is-glob": {
"version": "4.0.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -7025,7 +6810,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -7043,7 +6827,6 @@
},
"node_modules/is-number": {
"version": "7.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -7158,7 +6941,6 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
- "dev": true,
"engines": {
"node": ">=10"
},
@@ -7208,12 +6990,10 @@
},
"node_modules/isexe": {
"version": "2.0.0",
- "dev": true,
"license": "ISC"
},
"node_modules/istanbul-lib-coverage": {
"version": "3.2.0",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=8"
@@ -7221,7 +7001,6 @@
},
"node_modules/istanbul-lib-instrument": {
"version": "5.2.1",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@babel/core": "^7.12.3",
@@ -7236,7 +7015,6 @@
},
"node_modules/istanbul-lib-instrument/node_modules/semver": {
"version": "6.3.1",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -7530,7 +7308,6 @@
},
"node_modules/jest-diff": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
@@ -7589,7 +7366,6 @@
},
"node_modules/jest-get-type": {
"version": "29.4.3",
- "dev": true,
"license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7597,7 +7373,6 @@
},
"node_modules/jest-haste-map": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/types": "^29.5.0",
@@ -7634,7 +7409,6 @@
},
"node_modules/jest-matcher-utils": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
@@ -7648,7 +7422,6 @@
},
"node_modules/jest-message-util": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.12.13",
@@ -7667,7 +7440,6 @@
},
"node_modules/jest-mock": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/types": "^29.5.0",
@@ -7697,7 +7469,6 @@
},
"node_modules/jest-regex-util": {
"version": "29.4.3",
- "dev": true,
"license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7822,7 +7593,6 @@
},
"node_modules/jest-snapshot": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
@@ -7855,7 +7625,6 @@
},
"node_modules/jest-util": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/types": "^29.5.0",
@@ -7919,7 +7688,6 @@
},
"node_modules/jest-worker": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -7933,7 +7701,6 @@
},
"node_modules/jest-worker/node_modules/supports-color": {
"version": "8.1.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -7958,7 +7725,6 @@
},
"node_modules/js-tokens": {
"version": "4.0.0",
- "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
@@ -7973,7 +7739,6 @@
},
"node_modules/jsesc": {
"version": "2.5.2",
- "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -7989,12 +7754,10 @@
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
- "dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
- "dev": true,
"license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
@@ -8008,7 +7771,6 @@
},
"node_modules/json5": {
"version": "2.2.3",
- "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -8020,14 +7782,12 @@
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
- "dev": true
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dev": true,
"dependencies": {
"universalify": "^2.0.0"
},
@@ -8101,14 +7861,12 @@
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
- "dev": true,
"license": "MIT"
},
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
- "dev": true,
"engines": {
"node": ">=6.11.5"
}
@@ -8159,7 +7917,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
- "dev": true,
"dependencies": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
@@ -8211,7 +7968,6 @@
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz",
"integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==",
- "dev": true,
"engines": {
"node": ">=6"
},
@@ -8223,7 +7979,6 @@
"version": "0.30.1",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz",
"integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==",
- "dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
@@ -8262,7 +8017,6 @@
},
"node_modules/makeerror": {
"version": "1.0.12",
- "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"tmpl": "1.0.5"
@@ -8279,7 +8033,6 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
"integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
- "dev": true,
"dependencies": {
"fs-monkey": "^1.0.4"
},
@@ -8293,7 +8046,6 @@
},
"node_modules/merge-stream": {
"version": "2.0.0",
- "dev": true,
"license": "MIT"
},
"node_modules/merge2": {
@@ -8313,7 +8065,6 @@
},
"node_modules/micromatch": {
"version": "4.0.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.2",
@@ -8374,7 +8125,6 @@
},
"node_modules/minimatch": {
"version": "3.1.2",
- "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -8394,7 +8144,6 @@
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
"integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -8466,8 +8215,7 @@
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
- "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
- "dev": true
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"node_modules/mz": {
"version": "2.7.0",
@@ -8481,7 +8229,6 @@
},
"node_modules/natural-compare": {
"version": "1.4.0",
- "dev": true,
"license": "MIT"
},
"node_modules/natural-compare-lite": {
@@ -8499,7 +8246,6 @@
},
"node_modules/neo-async": {
"version": "2.6.2",
- "dev": true,
"license": "MIT"
},
"node_modules/no-case": {
@@ -8527,8 +8273,7 @@
"node_modules/node-abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
- "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
- "dev": true
+ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ=="
},
"node_modules/node-domexception": {
"version": "1.0.0",
@@ -8551,7 +8296,6 @@
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
"integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==",
- "dev": true,
"dependencies": {
"lodash": "^4.17.21"
}
@@ -8584,17 +8328,14 @@
},
"node_modules/node-int64": {
"version": "0.4.0",
- "dev": true,
"license": "MIT"
},
"node_modules/node-releases": {
"version": "2.0.12",
- "dev": true,
"license": "MIT"
},
"node_modules/normalize-path": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -8772,7 +8513,6 @@
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
- "dev": true,
"dependencies": {
"bl": "^4.1.0",
"chalk": "^4.1.0",
@@ -8795,7 +8535,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz",
"integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==",
- "dev": true,
"dependencies": {
"macos-release": "^2.5.0",
"windows-release": "^4.0.0"
@@ -8811,7 +8550,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -8854,7 +8592,6 @@
},
"node_modules/p-try": {
"version": "2.2.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -8867,7 +8604,6 @@
},
"node_modules/parent-module": {
"version": "1.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -8878,7 +8614,6 @@
},
"node_modules/parse-json": {
"version": "5.2.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -8920,7 +8655,6 @@
},
"node_modules/path-exists": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8928,7 +8662,6 @@
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -8936,7 +8669,6 @@
},
"node_modules/path-key": {
"version": "3.1.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8944,14 +8676,12 @@
},
"node_modules/path-parse": {
"version": "1.0.7",
- "dev": true,
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
- "dev": true,
"dependencies": {
"lru-cache": "^9.1.1 || ^10.0.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
@@ -8967,7 +8697,6 @@
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
"integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
- "dev": true,
"engines": {
"node": "14 || >=16.14"
}
@@ -8976,7 +8705,6 @@
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz",
"integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==",
- "dev": true,
"engines": {
"node": ">=16 || 14 >=14.17"
}
@@ -8987,7 +8715,6 @@
},
"node_modules/path-type": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8995,12 +8722,10 @@
},
"node_modules/picocolors": {
"version": "1.0.0",
- "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -9011,7 +8736,6 @@
},
"node_modules/pirates": {
"version": "4.0.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -9085,7 +8809,6 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
"integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
- "dev": true,
"engines": {
"node": ">=4"
}
@@ -9126,7 +8849,6 @@
},
"node_modules/pretty-format": {
"version": "29.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jest/schemas": "^29.4.3",
@@ -9139,7 +8861,6 @@
},
"node_modules/pretty-format/node_modules/ansi-styles": {
"version": "5.2.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -9191,7 +8912,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -9199,7 +8919,6 @@
},
"node_modules/punycode": {
"version": "2.3.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -9268,7 +8987,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -9317,7 +9035,6 @@
},
"node_modules/react-is": {
"version": "18.2.0",
- "dev": true,
"license": "MIT"
},
"node_modules/readable-stream": {
@@ -9339,7 +9056,6 @@
},
"node_modules/readdirp": {
"version": "3.6.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
@@ -9352,7 +9068,6 @@
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
- "dev": true,
"dependencies": {
"resolve": "^1.1.6"
},
@@ -9435,7 +9150,6 @@
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
- "dev": true,
"engines": {
"node": ">=0.10"
}
@@ -9451,14 +9165,12 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
"version": "1.22.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.11.0",
@@ -9500,7 +9212,6 @@
},
"node_modules/resolve-from": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9541,7 +9252,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "dev": true,
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
@@ -9554,7 +9264,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -9563,7 +9272,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
@@ -9697,7 +9405,6 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
- "dev": true,
"engines": {
"node": ">=0.12.0"
}
@@ -9771,7 +9478,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
- "dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
@@ -9849,7 +9555,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
"integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
- "dev": true,
"dependencies": {
"randombytes": "^2.1.0"
}
@@ -9885,7 +9590,6 @@
},
"node_modules/shebang-command": {
"version": "2.0.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -9896,7 +9600,6 @@
},
"node_modules/shebang-regex": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9906,7 +9609,6 @@
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
- "dev": true,
"dependencies": {
"glob": "^7.0.0",
"interpret": "^1.0.0",
@@ -9933,7 +9635,6 @@
},
"node_modules/signal-exit": {
"version": "3.0.7",
- "dev": true,
"license": "ISC"
},
"node_modules/sisteransi": {
@@ -9944,7 +9645,6 @@
},
"node_modules/slash": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9961,7 +9661,6 @@
},
"node_modules/source-map": {
"version": "0.6.1",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -9969,7 +9668,6 @@
},
"node_modules/source-map-support": {
"version": "0.5.21",
- "dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
@@ -9990,12 +9688,10 @@
},
"node_modules/sprintf-js": {
"version": "1.0.3",
- "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/stack-utils": {
"version": "2.0.6",
- "dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^2.0.0"
@@ -10006,7 +9702,6 @@
},
"node_modules/stack-utils/node_modules/escape-string-regexp": {
"version": "2.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -10119,7 +9814,6 @@
},
"node_modules/strip-bom": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -10159,7 +9853,6 @@
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -10177,7 +9870,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
"integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
- "dev": true,
"engines": {
"node": ">=0.10"
}
@@ -10211,7 +9903,6 @@
},
"node_modules/tapable": {
"version": "2.2.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -10221,7 +9912,6 @@
"version": "5.19.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
"integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
- "dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -10239,7 +9929,6 @@
"version": "5.3.9",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
"integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
- "dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
@@ -10273,7 +9962,6 @@
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
"integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
- "dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -10283,7 +9971,6 @@
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
- "dev": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -10297,7 +9984,6 @@
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -10311,12 +9997,10 @@
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/test-exclude": {
"version": "6.0.0",
- "dev": true,
"license": "ISC",
"dependencies": {
"@istanbuljs/schema": "^0.1.2",
@@ -10354,8 +10038,7 @@
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
- "dev": true
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"node_modules/time-constants": {
"version": "1.0.3",
@@ -10376,7 +10059,6 @@
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "dev": true,
"dependencies": {
"os-tmpdir": "~1.0.2"
},
@@ -10386,12 +10068,10 @@
},
"node_modules/tmpl": {
"version": "1.0.5",
- "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -10399,7 +10079,6 @@
},
"node_modules/to-regex-range": {
"version": "5.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@@ -10421,7 +10100,6 @@
},
"node_modules/tree-kill": {
"version": "1.2.2",
- "dev": true,
"license": "MIT",
"bin": {
"tree-kill": "cli.js"
@@ -10579,7 +10257,6 @@
},
"node_modules/tsconfig-paths": {
"version": "4.2.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"json5": "^2.2.2",
@@ -10594,7 +10271,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz",
"integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==",
- "dev": true,
"dependencies": {
"chalk": "^4.1.0",
"enhanced-resolve": "^5.7.0",
@@ -10648,7 +10324,6 @@
},
"node_modules/type-detect": {
"version": "4.0.8",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -10853,7 +10528,6 @@
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
"integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
- "devOptional": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10902,7 +10576,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
- "dev": true,
"engines": {
"node": ">= 10.0.0"
}
@@ -10924,7 +10597,6 @@
},
"node_modules/update-browserslist-db": {
"version": "1.0.11",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -10961,7 +10633,6 @@
},
"node_modules/uri-js": {
"version": "4.4.1",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -11057,7 +10728,6 @@
},
"node_modules/walker": {
"version": "1.0.8",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"makeerror": "1.0.12"
@@ -11067,7 +10737,6 @@
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
- "dev": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -11080,7 +10749,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
- "dev": true,
"dependencies": {
"defaults": "^1.0.3"
}
@@ -11100,7 +10768,6 @@
"version": "5.88.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
- "dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
@@ -11147,7 +10814,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz",
"integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -11156,7 +10822,6 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
- "dev": true,
"engines": {
"node": ">=10.13.0"
}
@@ -11171,7 +10836,6 @@
},
"node_modules/which": {
"version": "2.0.2",
- "dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -11221,7 +10885,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz",
"integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==",
- "dev": true,
"dependencies": {
"execa": "^4.0.2"
},
@@ -11236,7 +10899,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
- "dev": true,
"dependencies": {
"cross-spawn": "^7.0.0",
"get-stream": "^5.0.0",
@@ -11259,7 +10921,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
- "dev": true,
"dependencies": {
"pump": "^3.0.0"
},
@@ -11274,7 +10935,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
- "dev": true,
"engines": {
"node": ">=8.12.0"
}
@@ -11283,7 +10943,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "dev": true,
"engines": {
"node": ">=8"
},
@@ -11295,7 +10954,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -11304,7 +10962,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
"dependencies": {
"path-key": "^3.0.0"
},
@@ -11316,7 +10973,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
@@ -11331,7 +10987,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true,
"engines": {
"node": ">=6"
}
@@ -11362,7 +11017,6 @@
},
"node_modules/write-file-atomic": {
"version": "4.0.2",
- "dev": true,
"license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4",
@@ -11413,7 +11067,6 @@
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "dev": true,
"engines": {
"node": ">= 6"
}
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 5505a040..38f9869f 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -31,6 +31,7 @@
},
"homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
"dependencies": {
+ "@jest/globals": "^29.5.0",
"@frequency-chain/api-augment": "1.7.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
@@ -63,7 +64,6 @@
"time-constants": "^1.0.3"
},
"devDependencies": {
- "@jest/globals": "^29.5.0",
"@polkadot/typegen": "10.9.1",
"@types/jest": "^29.5.2",
"@types/time-constants": "^1.0.0",
From da2cd74026a28348490002e4f0de734b3991f343 Mon Sep 17 00:00:00 2001
From: Aramik
Date: Tue, 29 Aug 2023 10:36:44 -0700
Subject: [PATCH 007/137] Added api validation (#17)
* Added api validation
* added audio mimes
* added tests
---
.../apps/api/src/api.controller.ts | 47 +-
.../content-watcher/apps/api/src/metadata.ts | 2 +-
.../apps/api/test/app.e2e-spec.ts | 549 +++++++
.../apps/api/test/jest-e2e.json | 9 +
.../worker/src/publisher/ipfs.publisher.ts | 25 +-
services/content-watcher/jest.config.js | 7 -
.../libs/common/src/constants.ts | 32 +
.../libs/common/src/dtos/activity.dto.ts | 115 +-
.../libs/common/src/dtos/announcement.dto.ts | 30 +-
.../libs/common/src/dtos/common.dto.ts | 13 +
services/content-watcher/package-lock.json | 1411 +++++++++--------
services/content-watcher/package.json | 42 +-
12 files changed, 1616 insertions(+), 666 deletions(-)
create mode 100644 services/content-watcher/apps/api/test/app.e2e-spec.ts
create mode 100644 services/content-watcher/apps/api/test/jest-e2e.json
delete mode 100644 services/content-watcher/jest.config.js
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index 369d2916..a32d30ac 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -1,8 +1,20 @@
-import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, Post, Put, UploadedFile, UploadedFiles, UseInterceptors } from '@nestjs/common';
+import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, ParseFilePipeBuilder, Post, Put, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { v4 as uuidv4 } from 'uuid';
import { FilesInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes } from '@nestjs/swagger';
-import { BroadcastDto, ReactionDto, ReplyDto, UpdateDto, ProfileDto, AnnouncementResponseDto, FilesUploadDto, UploadResponseDto } from '../../../libs/common/src';
+import {
+ BroadcastDto,
+ ReactionDto,
+ ReplyDto,
+ UpdateDto,
+ ProfileDto,
+ AnnouncementResponseDto,
+ FilesUploadDto,
+ UploadResponseDto,
+ DsnpUserIdParam,
+ DsnpContentHashParam,
+} from '../../../libs/common/src';
+import { DSNP_VALID_MIME_TYPES } from '../../../libs/common/src/constants';
@Controller('api')
export class ApiController {
@@ -28,8 +40,23 @@ export class ApiController {
description: 'Asset files',
type: FilesUploadDto,
})
- // eslint-disable-next-line no-undef
- async assetUpload(@UploadedFiles() files: Array): Promise {
+ async assetUpload(
+ @UploadedFiles(
+ new ParseFilePipeBuilder()
+ .addFileTypeValidator({
+ fileType: DSNP_VALID_MIME_TYPES,
+ })
+ .addMaxSizeValidator({
+ // this is in bytes (2 GB)
+ maxSize: 2 * 1000 * 1000 * 1000,
+ })
+ .build({
+ errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
+ }),
+ )
+ files: // eslint-disable-next-line no-undef
+ Array,
+ ): Promise {
this.logger.log(`upload ${files.length}`);
return {
assetIds: files.map((_) => uuidv4()),
@@ -38,7 +65,7 @@ export class ApiController {
@Post('content/:userDsnpId/broadcast')
@HttpCode(202)
- async broadcast(@Param('userDsnpId') userDsnpId: string, @Body() broadcastDto: BroadcastDto): Promise {
+ async broadcast(@Param() userDsnpId: DsnpUserIdParam, @Body() broadcastDto: BroadcastDto): Promise {
this.logger.log(`broadcast ${userDsnpId}`);
return {
referenceId: uuidv4(),
@@ -47,7 +74,7 @@ export class ApiController {
@Post('content/:userDsnpId/reply')
@HttpCode(202)
- async reply(@Param('userDsnpId') userDsnpId: string, @Body() replyDto: ReplyDto): Promise {
+ async reply(@Param() userDsnpId: DsnpUserIdParam, @Body() replyDto: ReplyDto): Promise {
this.logger.log(`reply ${userDsnpId}`);
return {
referenceId: uuidv4(),
@@ -56,7 +83,7 @@ export class ApiController {
@Post('content/:userDsnpId/reaction')
@HttpCode(202)
- async reaction(@Param('userDsnpId') userDsnpId: string, @Body() reactionDto: ReactionDto): Promise {
+ async reaction(@Param() userDsnpId: DsnpUserIdParam, @Body() reactionDto: ReactionDto): Promise {
this.logger.log(`reaction ${userDsnpId}`);
return {
referenceId: uuidv4(),
@@ -65,7 +92,7 @@ export class ApiController {
@Put('content/:userDsnpId/:targetContentHash')
@HttpCode(202)
- async update(@Param('userDsnpId') userDsnpId: string, @Param('targetContentHash') targetContentHash: string, @Body() updateDto: UpdateDto): Promise {
+ async update(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam, @Body() updateDto: UpdateDto): Promise {
this.logger.log(`update ${userDsnpId}/${targetContentHash}`);
return {
referenceId: uuidv4(),
@@ -74,7 +101,7 @@ export class ApiController {
@Delete('content/:userDsnpId/:targetContentHash')
@HttpCode(202)
- async delete(@Param('userDsnpId') userDsnpId: string, @Param('targetContentHash') targetContentHash: string): Promise {
+ async delete(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam): Promise {
this.logger.log(`delete ${userDsnpId}/${targetContentHash}`);
return {
referenceId: uuidv4(),
@@ -83,7 +110,7 @@ export class ApiController {
@Put('profile/:userDsnpId')
@HttpCode(202)
- async profile(@Param('userDsnpId') userDsnpId: string, @Body() profileDto: ProfileDto): Promise {
+ async profile(@Param() userDsnpId: DsnpUserIdParam, @Body() profileDto: ProfileDto): Promise {
this.logger.log(`profile ${userDsnpId}`);
return {
referenceId: uuidv4(),
diff --git a/services/content-watcher/apps/api/src/metadata.ts b/services/content-watcher/apps/api/src/metadata.ts
index 91a614a2..71c2be77 100644
--- a/services/content-watcher/apps/api/src/metadata.ts
+++ b/services/content-watcher/apps/api/src/metadata.ts
@@ -5,5 +5,5 @@ export default async () => {
["../../../libs/common/src/dtos/announcement.dto"]: await import("../../../libs/common/src/dtos/announcement.dto"),
["../../../libs/common/src/dtos/common.dto"]: await import("../../../libs/common/src/dtos/common.dto")
};
- return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LinkDto": { href: { required: true, type: () => String }, name: { required: false, type: () => String } }, "LocationDto": { name: { required: true, type: () => String }, accuracy: { required: false, type: () => Number }, altitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String }, height: { required: false, type: () => Number }, width: { required: false, type: () => Number }, duration: { required: false, type: () => String } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String }, mentionedId: { required: false, type: () => String } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: true, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String }, href: { required: false, type: () => String } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String }, published: { required: true, type: () => String }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].AnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String }, apply: { required: true, type: () => Number }, inReplyTo: { required: true, type: () => String } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }]] } };
+ return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LocationDto": { name: { required: true, type: () => String, minLength: 1 }, accuracy: { required: false, type: () => Number, minimum: 0, maximum: 100 }, altitude: { required: false, type: () => Number }, latitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number, minimum: 0 }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String, minLength: 1 }, height: { required: false, type: () => Number, minimum: 1 }, width: { required: false, type: () => Number, minimum: 1 }, duration: { required: false, type: () => String, pattern: "DURATION_REGEX" } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String, minLength: 1 }, mentionedId: { required: false, type: () => String, minLength: 1, pattern: "DSNP_USER_URI_REGEX" } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String, minLength: 1 }, href: { required: false, type: () => String, minLength: 1 } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String, minLength: 1 }, published: { required: true, type: () => String, pattern: "ISO8601_REGEX" }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String, pattern: "ISO8601_REGEX" } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].AnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String, minLength: 1, pattern: "DSNP_EMOJI_REGEX" }, apply: { required: true, type: () => Number, minimum: 0, maximum: 255 }, inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "DsnpUserIdParam": { userDsnpId: { required: true, type: () => String } }, "DsnpContentHashParam": { targetContentHash: { required: true, type: () => String } }, "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }]] } };
};
\ No newline at end of file
diff --git a/services/content-watcher/apps/api/test/app.e2e-spec.ts b/services/content-watcher/apps/api/test/app.e2e-spec.ts
new file mode 100644
index 00000000..b6786248
--- /dev/null
+++ b/services/content-watcher/apps/api/test/app.e2e-spec.ts
@@ -0,0 +1,549 @@
+/* eslint-disable import/no-extraneous-dependencies */
+/* eslint-disable no-undef */
+import { INestApplication, ValidationPipe } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing';
+import request from 'supertest';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { ApiModule } from '../src/api.module';
+
+describe('AppController E2E request verification!', () => {
+ let app: INestApplication;
+ let module: TestingModule;
+ const validlocation = {
+ name: 'name of location',
+ accuracy: 97,
+ altitude: 10,
+ latitude: 37.26,
+ longitude: -119.59,
+ radius: 10,
+ units: 'm',
+ };
+ const validTags = [
+ {
+ type: 'mention',
+ mentionedId: 'dsnp://78187493520',
+ },
+ {
+ type: 'hashtag',
+ name: '#taggedUser',
+ },
+ ];
+ const validContent = {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: 'reference-id-1',
+ height: 123,
+ width: 321,
+ },
+ ],
+ },
+ {
+ type: 'link',
+ name: 'link asset',
+ href: 'http://example.com',
+ },
+ ],
+ name: 'name of note content',
+ tag: validTags,
+ location: validlocation,
+ };
+ const validBroadCast = {
+ content: validContent,
+ };
+ const validReply = {
+ content: validContent,
+ inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
+ };
+ const validReaction = {
+ emoji: '🤌🏼',
+ apply: 5,
+ inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
+ };
+ const validProfile = {
+ icon: [
+ {
+ referenceId: 'reference-id-1',
+ height: 123,
+ width: 321,
+ },
+ ],
+ summary: 'profile summary',
+ published: '1970-01-01T00:00:00+00:00',
+ name: 'name of profile content',
+ tag: validTags,
+ location: validlocation,
+ };
+
+ beforeEach(async () => {
+ module = await Test.createTestingModule({
+ imports: [ApiModule],
+ }).compile();
+
+ app = module.createNestApplication();
+ const eventEmitter = app.get(EventEmitter2);
+ eventEmitter.on('shutdown', async () => {
+ await app.close();
+ });
+ app.useGlobalPipes(new ValidationPipe());
+ app.enableShutdownHooks();
+ await app.init();
+ });
+
+ it('(GET) /api/health', () => request(app.getHttpServer()).get('/api/health').expect(200).expect({ status: 200 }));
+
+ describe('Validate Route params', () => {
+ it('invalid userDsnpId should fail', async () => {
+ const invalidDsnpUserId = '2gsjhdaj';
+ return request(app.getHttpServer())
+ .post(`/api/content/${invalidDsnpUserId}/broadcast`)
+ .send(validBroadCast)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('must be a number string'));
+ });
+
+ it('invalid DsnpContentHashParam should fail', () => {
+ const invalidContentHashParam = '2gsjhdaj';
+ return request(app.getHttpServer())
+ .delete(`/api/content/123/${invalidContentHashParam}`)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('must be in hexadecimal format'));
+ });
+ });
+
+ describe('(POST) /api/content/:dsnpUserId/broadcast', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(validBroadCast)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('empty body should fail', () => {
+ const body = {};
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('should not be empty'));
+ });
+
+ it('empty content should fail', () => {
+ const body = {
+ content: {
+ content: '',
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('content must be longer than or equal to 1 characters'));
+ });
+
+ it('empty published should fail', () => {
+ const body = {
+ content: {
+ content: 'tests content',
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('published must match'));
+ });
+
+ it('invalid published should fail', () => {
+ const body2 = {
+ content: {
+ content: 'tests content',
+ published: '1980',
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body2)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('published must match'));
+ });
+
+ it('invalid assets type should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'invalid',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('type must be one of the following values'));
+ });
+
+ it('image asset without references should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'image',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('references should not be empty'));
+ });
+
+ it('image asset with non unique references id should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'image',
+ references: [
+ {
+ referenceId: 'reference-id-1',
+ },
+ {
+ referenceId: 'reference-id-1',
+ },
+ ],
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('elements must be unique'));
+ });
+
+ it('link asset without href should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'link',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('href must be longer than or equal to 1 character'));
+ });
+
+ it('link asset with invalid href protocol should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ assets: [
+ {
+ type: 'link',
+ href: 'ftp://sgdjas8912yejc.com',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('href must be a URL address'));
+ });
+
+ it('hashtag without name should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ tag: [
+ {
+ type: 'hashtag',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('name must be longer than or equal to 1 character'));
+ });
+
+ it('mentioned tag without mentionedId should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ tag: [
+ {
+ type: 'mention',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('mentionedId must be longer than or equal to 1 character'));
+ });
+
+ it('invalid tag type should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ tag: [
+ {
+ type: 'invalid',
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('type must be one of the following values'));
+ });
+
+ it('location with invalid units should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ location: {
+ name: 'name of location',
+ units: 'invalid',
+ },
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('units must be one of the following values'));
+ });
+
+ it('location with empty name should fail', () => {
+ const body = {
+ content: {
+ content: 'test broadcast message',
+ published: '1970-01-01T00:00:00+00:00',
+ location: {
+ name: '',
+ },
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('name must be longer than or equal to 1 characters'));
+ });
+ });
+
+ describe('(POST) /api/content/:dsnpUserId/reply', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send(validReply)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('empty body should fail', () => {
+ const body = {};
+ return request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send(body)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('should not be empty'));
+ });
+
+ it('empty inReplyTo should fail', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send({
+ content: validContent,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('inReplyTo must be a string')));
+
+ it('invalid inReplyTo should fail', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send({
+ content: validContent,
+ inReplyTo: 'shgdjas72gsjajasa',
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('inReplyTo must match')));
+ });
+
+ describe('(POST) /api/content/:dsnpUserId/reaction', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reaction`)
+ .send(validReaction)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('valid emoji should fail', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reaction`)
+ .send({
+ emoji: '2',
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('emoji must match')));
+
+ it('valid apply amount should fail', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reaction`)
+ .send({
+ emoji: '😀',
+ apply: -1,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('apply must not be less than 0')));
+
+ it('invalid inReplyTo should fail', () =>
+ request(app.getHttpServer())
+ .post(`/api/content/123/reaction`)
+ .send({
+ emoji: '😀',
+ apply: 0,
+ inReplyTo: 'shgdjas72gsjajasa',
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('inReplyTo must match')));
+ });
+
+ describe('(PUT) /api/content/:dsnpUserId/:contentHash', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .put(`/api/content/123/0x7653423447AF`)
+ .send({
+ targetAnnouncementType: 'broadcast',
+ content: validContent,
+ })
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('invalid targetAnnouncementType should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/content/123/0x7653423447AF`)
+ .send({
+ targetAnnouncementType: 'invalid',
+ content: validContent,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('targetAnnouncementType must be one of the following values')));
+ });
+
+ describe('(DELETE) /api/content/:dsnpUserId/contentHash', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .delete(`/api/content/123/0x7653423447AF`)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+ });
+
+ describe('(PUT) /api/profile/:userDsnpId', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: validProfile,
+ })
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('empty profile should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({})
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('should not be empty')));
+
+ it('invalid published should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: {
+ published: '1980',
+ },
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('published must match')));
+
+ it('non unique reference ids should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: {
+ icon: [
+ {
+ referenceId: 'reference-id-1',
+ },
+ {
+ referenceId: 'reference-id-1',
+ },
+ ],
+ },
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('elements must be unique')));
+ });
+
+ describe('(PUT) /api/asset/upload', () => {
+ it('valid request should work!', () =>
+ request(app.getHttpServer())
+ .put(`/api/asset/upload`)
+ .attach('files', Buffer.from(validContent.toString()), 'image.jpg')
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('assetIds')));
+
+ it('invalid mime should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/asset/upload`)
+ .attach('files', Buffer.from(validContent.toString()), 'doc.txt')
+ .expect(422)
+ .expect((res) => expect(res.text).toContain('expected type is')));
+ });
+
+ afterEach(async () => {
+ try {
+ await app.close();
+ } catch (err) {
+ console.error(err);
+ }
+ });
+});
diff --git a/services/content-watcher/apps/api/test/jest-e2e.json b/services/content-watcher/apps/api/test/jest-e2e.json
new file mode 100644
index 00000000..e9d912f3
--- /dev/null
+++ b/services/content-watcher/apps/api/test/jest-e2e.json
@@ -0,0 +1,9 @@
+{
+ "moduleFileExtensions": ["js", "json", "ts"],
+ "rootDir": ".",
+ "testEnvironment": "node",
+ "testRegex": ".e2e-spec.ts$",
+ "transform": {
+ "^.+\\.(t|j)s$": "ts-jest"
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
index 726cd033..064c77fd 100644
--- a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
+++ b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
@@ -12,7 +12,11 @@ import { createKeys } from '../blockchain/create-keys';
export class IPFSPublisher {
private logger: Logger;
- constructor(private configService: ConfigService, private blockchainService: BlockchainService, private eventEmitter: EventEmitter2) {
+ constructor(
+ private configService: ConfigService,
+ private blockchainService: BlockchainService,
+ private eventEmitter: EventEmitter2,
+ ) {
this.logger = new Logger(IPFSPublisher.name);
}
@@ -47,14 +51,17 @@ export class IPFSPublisher {
});
const totalCapUsedPerEpoch = await Promise.all(batchPromises);
- const totalCapacityUsed = totalCapUsedPerEpoch.reduce((acc, curr) => {
- const epoch = Object.keys(curr)[0];
- if (acc[epoch]) {
- acc[epoch] += curr[epoch];
- }
- acc[epoch] = curr[epoch];
- return acc;
- }, {} as { [key: string]: bigint });
+ const totalCapacityUsed = totalCapUsedPerEpoch.reduce(
+ (acc, curr) => {
+ const epoch = Object.keys(curr)[0];
+ if (acc[epoch]) {
+ acc[epoch] += curr[epoch];
+ }
+ acc[epoch] = curr[epoch];
+ return acc;
+ },
+ {} as { [key: string]: bigint },
+ );
this.logger.debug(`Total capacity used: ${JSON.stringify(totalCapacityUsed)}`);
return totalCapacityUsed;
diff --git a/services/content-watcher/jest.config.js b/services/content-watcher/jest.config.js
deleted file mode 100644
index 7eb5e95a..00000000
--- a/services/content-watcher/jest.config.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/** @type {import('ts-jest').JestConfigWithTsJest} */
-module.exports = {
- preset: 'ts-jest',
- testEnvironment: 'node',
- setupFiles: ["dotenv/config"],
- testPathIgnorePatterns: ['/dist']
-};
diff --git a/services/content-watcher/libs/common/src/constants.ts b/services/content-watcher/libs/common/src/constants.ts
index a7df8f39..94798661 100644
--- a/services/content-watcher/libs/common/src/constants.ts
+++ b/services/content-watcher/libs/common/src/constants.ts
@@ -1,2 +1,34 @@
+/**
+ * Regex for ISO 8601
+ * - T separation
+ * - Required Time
+ * - Supports fractional seconds
+ * - Z or hour minute offset
+ */
+export const ISO8601_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,})?(Z|[+-][01][0-9]:[0-5][0-9])?$/;
+/**
+ * DSNP user URI based on DSNP Spec
+ * example: dsnp://78187493520
+ */
+export const DSNP_USER_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}$/i;
+/**
+ * DSNP content URI based on DSNP Spec
+ * example: dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+ */
+export const DSNP_CONTENT_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}\/0x[0-9a-f]+$/i;
+/**
+ * DSNP character ranges for valid emojis
+ */
+export const DSNP_EMOJI_REGEX = /^[\u{2000}-\u{2BFF}\u{E000}-\u{FFFF}\u{1F000}-\u{FFFFF}]+$/u;
+/**
+ * Activity Stream Duration based on https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
+ */
+export const DURATION_REGEX = /^-?P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+(\.[0-9]+)?S)?)?)+$/;
+
+/**
+ * Dsnp attachments mime types
+ */
+export const DSNP_VALID_MIME_TYPES =
+ /(image\/jpeg|image\/png|image\/svg\+xml|image\/webp|image\/gif|video\/mpeg|video\/ogg|video\/webm|video\/H256|video\/mp4|audio\/mpeg|audio\/ogg|audio\/webm)$/;
export const SECONDS_PER_BLOCK = 12;
export const CAPACITY_EPOCH_TIMEOUT_NAME = 'capacity-epoch-timeout';
diff --git a/services/content-watcher/libs/common/src/dtos/activity.dto.ts b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
index 1b37f27a..34cd367f 100644
--- a/services/content-watcher/libs/common/src/dtos/activity.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
@@ -1,7 +1,30 @@
/**
* File name should always end with `.dto.ts` for swagger metadata generator to get picked up
*/
-// eslint-disable-next-line no-shadow,max-classes-per-file
+// eslint-disable-next-line max-classes-per-file
+import {
+ ArrayNotEmpty,
+ ArrayUnique,
+ IsArray,
+ IsEnum,
+ IsLatitude,
+ IsLongitude,
+ IsNumber,
+ IsOptional,
+ IsPositive,
+ IsString,
+ IsUrl,
+ Matches,
+ Max,
+ Min,
+ MinLength,
+ ValidateIf,
+ ValidateNested,
+} from 'class-validator';
+import { Type } from 'class-transformer';
+import { DSNP_USER_URI_REGEX, DURATION_REGEX, ISO8601_REGEX } from '../constants';
+
+// eslint-disable-next-line no-shadow
export enum UnitTypeDto {
CM = 'cm',
M = 'm',
@@ -25,74 +48,148 @@ export enum AttachmentTypeDto {
VIDEO = 'video',
}
-export class LinkDto {
- href: string;
-
- name?: string;
-}
-
export class LocationDto {
+ @MinLength(1)
+ @IsString()
name: string;
+ @IsOptional()
+ @IsNumber()
+ @Min(0)
+ @Max(100)
accuracy?: number;
+ @IsOptional()
+ @IsNumber()
altitude?: number;
+ @IsOptional()
+ @IsNumber()
+ @IsLatitude()
+ latitude?: number;
+
+ @IsOptional()
+ @IsNumber()
+ @IsLongitude()
longitude?: number;
+ @IsOptional()
+ @IsNumber()
+ @Min(0)
radius?: number;
+ @IsOptional()
+ @IsEnum(UnitTypeDto)
units?: UnitTypeDto;
}
export class AssetReferenceDto {
+ @MinLength(1)
+ @IsString()
referenceId: string;
+ @IsOptional()
+ @IsNumber()
+ @IsPositive()
height?: number;
+ @IsOptional()
+ @IsNumber()
+ @IsPositive()
width?: number;
+ @IsOptional()
+ @IsString()
+ @Matches(DURATION_REGEX)
duration?: string;
}
export class TagDto {
+ @IsEnum(TagTypeDto)
type: TagTypeDto;
+ @ValidateIf((o) => o.type === TagTypeDto.Hashtag)
+ @MinLength(1)
+ @IsString()
name?: string;
+ @ValidateIf((o) => o.type === TagTypeDto.Mention)
+ @MinLength(1)
+ @IsString()
+ @Matches(DSNP_USER_URI_REGEX)
mentionedId?: string;
}
export class AssetDto {
+ @IsEnum(AttachmentTypeDto)
type: AttachmentTypeDto;
- references: Array;
-
+ @ValidateIf((o) => o.type !== AttachmentTypeDto.LINK)
+ @ValidateNested({ each: true })
+ @IsArray()
+ @ArrayNotEmpty()
+ @ArrayUnique((o) => o.referenceId)
+ @Type(() => AssetReferenceDto)
+ references?: Array;
+
+ @IsOptional()
+ @IsString()
+ @MinLength(1)
name?: string;
+ @ValidateIf((o) => o.type === AttachmentTypeDto.LINK)
+ @IsString()
+ @MinLength(1)
+ @IsUrl({ protocols: ['http', 'https'] })
href?: string;
}
export class BaseActivityDto {
+ @IsOptional()
name?: string;
+ @IsOptional()
+ @ValidateNested({ each: true })
+ @IsArray()
+ @Type(() => TagDto)
tag?: Array;
+ @IsOptional()
+ @ValidateNested()
+ @Type(() => LocationDto)
location?: LocationDto;
}
export class NoteActivityDto extends BaseActivityDto {
+ @MinLength(1)
+ @IsString()
content: string;
+ @IsString()
+ @Matches(ISO8601_REGEX)
published: string;
+ @IsOptional()
+ @ValidateNested({ each: true })
+ @IsArray()
+ @Type(() => AssetDto)
assets?: Array;
}
export class ProfileActivityDto extends BaseActivityDto {
+ @IsOptional()
+ @ValidateNested({ each: true })
+ @IsArray()
+ @ArrayUnique((o) => o.referenceId)
+ @Type(() => AssetReferenceDto)
icon?: Array;
+ @IsOptional()
+ @IsString()
summary?: string;
+ @IsOptional()
+ @IsString()
+ @Matches(ISO8601_REGEX)
published?: string;
}
diff --git a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
index f684c4e1..8466d931 100644
--- a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
@@ -2,42 +2,64 @@
* File name should always end with `.dto.ts` for swagger metadata generator to get picked up
*/
// eslint-disable-next-line max-classes-per-file
+import { IsEnum, IsInt, IsNotEmpty, IsString, Matches, Max, MaxLength, Min, MinLength, ValidateNested } from 'class-validator';
+import { Type } from 'class-transformer';
import { NoteActivityDto, ProfileActivityDto } from './activity.dto';
+import { DSNP_CONTENT_URI_REGEX, DSNP_EMOJI_REGEX } from '../constants';
// eslint-disable-next-line no-shadow
export enum AnnouncementTypeDto {
- TOMBSTONE = 'tombstone',
BROADCAST = 'broadcast',
REPLY = 'reply',
- REACTION = 'reaction',
- PROFILE = 'profile',
- UPDATE = 'update',
}
export class BroadcastDto {
+ @IsNotEmpty()
+ @ValidateNested()
+ @Type(() => NoteActivityDto)
content: NoteActivityDto;
}
export class ReplyDto {
+ @IsString()
+ @Matches(DSNP_CONTENT_URI_REGEX)
inReplyTo: string;
+ @IsNotEmpty()
+ @ValidateNested()
+ @Type(() => NoteActivityDto)
content: NoteActivityDto;
}
export class UpdateDto {
+ @IsEnum(AnnouncementTypeDto)
targetAnnouncementType: AnnouncementTypeDto;
+ @IsNotEmpty()
+ @ValidateNested()
+ @Type(() => NoteActivityDto)
content: NoteActivityDto;
}
export class ReactionDto {
+ @MinLength(1)
+ @IsString()
+ @Matches(DSNP_EMOJI_REGEX)
emoji: string;
+ @IsInt()
+ @Min(0)
+ @Max(255)
apply: number;
+ @IsString()
+ @Matches(DSNP_CONTENT_URI_REGEX)
inReplyTo: string;
}
export class ProfileDto {
+ @IsNotEmpty()
+ @ValidateNested()
+ @Type(() => ProfileActivityDto)
profile: ProfileActivityDto;
}
diff --git a/services/content-watcher/libs/common/src/dtos/common.dto.ts b/services/content-watcher/libs/common/src/dtos/common.dto.ts
index 9fd836aa..6b325f1e 100644
--- a/services/content-watcher/libs/common/src/dtos/common.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/common.dto.ts
@@ -3,6 +3,19 @@
*/
// eslint-disable-next-line max-classes-per-file
import { ApiProperty } from '@nestjs/swagger';
+import { IsHexadecimal, IsNotEmpty, IsNumberString } from 'class-validator';
+
+export class DsnpUserIdParam {
+ @IsNotEmpty()
+ @IsNumberString({ no_symbols: true })
+ userDsnpId: string;
+}
+
+export class DsnpContentHashParam {
+ @IsNotEmpty()
+ @IsHexadecimal({ message: 'targetContentHash must be in hexadecimal format!' })
+ targetContentHash: string;
+}
export class AnnouncementResponseDto {
referenceId: string;
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index ef07ccf5..1bc6bcab 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -43,7 +43,10 @@
},
"devDependencies": {
"@polkadot/typegen": "10.9.1",
+ "@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
+ "@types/node": "^20.3.1",
+ "@types/supertest": "^2.0.12",
"@types/time-constants": "^1.0.0",
"@typescript-eslint/parser": "^5.59.8",
"@typescript-eslint/typescript-estree": "5.59.8",
@@ -56,10 +59,12 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-nestjs": "^1.2.3",
- "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
"license-report": "^6.4.0",
+ "supertest": "^6.3.3",
"ts-jest": "^29.1.0",
+ "ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^4.2.0",
@@ -668,11 +673,12 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.22.3",
- "license": "MIT",
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz",
+ "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==",
"peer": true,
"dependencies": {
- "regenerator-runtime": "^0.13.11"
+ "regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
@@ -730,8 +736,9 @@
},
"node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/@colors/colors": {
@@ -951,16 +958,17 @@
}
},
"node_modules/@jest/console": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz",
+ "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^29.5.0",
- "jest-util": "^29.5.0",
+ "jest-message-util": "^29.6.3",
+ "jest-util": "^29.6.3",
"slash": "^3.0.0"
},
"engines": {
@@ -968,37 +976,38 @@
}
},
"node_modules/@jest/core": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz",
+ "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.5.0",
- "@jest/reporters": "^29.5.0",
- "@jest/test-result": "^29.5.0",
- "@jest/transform": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/console": "^29.6.4",
+ "@jest/reporters": "^29.6.4",
+ "@jest/test-result": "^29.6.4",
+ "@jest/transform": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.9",
- "jest-changed-files": "^29.5.0",
- "jest-config": "^29.5.0",
- "jest-haste-map": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-regex-util": "^29.4.3",
- "jest-resolve": "^29.5.0",
- "jest-resolve-dependencies": "^29.5.0",
- "jest-runner": "^29.5.0",
- "jest-runtime": "^29.5.0",
- "jest-snapshot": "^29.5.0",
- "jest-util": "^29.5.0",
- "jest-validate": "^29.5.0",
- "jest-watcher": "^29.5.0",
+ "jest-changed-files": "^29.6.3",
+ "jest-config": "^29.6.4",
+ "jest-haste-map": "^29.6.4",
+ "jest-message-util": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.6.4",
+ "jest-resolve-dependencies": "^29.6.4",
+ "jest-runner": "^29.6.4",
+ "jest-runtime": "^29.6.4",
+ "jest-snapshot": "^29.6.4",
+ "jest-util": "^29.6.3",
+ "jest-validate": "^29.6.3",
+ "jest-watcher": "^29.6.4",
"micromatch": "^4.0.4",
- "pretty-format": "^29.5.0",
+ "pretty-format": "^29.6.3",
"slash": "^3.0.0",
"strip-ansi": "^6.0.0"
},
@@ -1015,79 +1024,85 @@
}
},
"node_modules/@jest/environment": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz",
+ "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==",
"dependencies": {
- "@jest/fake-timers": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/fake-timers": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
- "jest-mock": "^29.5.0"
+ "jest-mock": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/expect": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz",
+ "integrity": "sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==",
"dependencies": {
- "expect": "^29.5.0",
- "jest-snapshot": "^29.5.0"
+ "expect": "^29.6.4",
+ "jest-snapshot": "^29.6.4"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/expect-utils": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz",
+ "integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==",
"dependencies": {
- "jest-get-type": "^29.4.3"
+ "jest-get-type": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/fake-timers": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz",
+ "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==",
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@sinonjs/fake-timers": "^10.0.2",
"@types/node": "*",
- "jest-message-util": "^29.5.0",
- "jest-mock": "^29.5.0",
- "jest-util": "^29.5.0"
+ "jest-message-util": "^29.6.3",
+ "jest-mock": "^29.6.3",
+ "jest-util": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/globals": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz",
+ "integrity": "sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==",
"dependencies": {
- "@jest/environment": "^29.5.0",
- "@jest/expect": "^29.5.0",
- "@jest/types": "^29.5.0",
- "jest-mock": "^29.5.0"
+ "@jest/environment": "^29.6.4",
+ "@jest/expect": "^29.6.4",
+ "@jest/types": "^29.6.3",
+ "jest-mock": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/reporters": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz",
+ "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^29.5.0",
- "@jest/test-result": "^29.5.0",
- "@jest/transform": "^29.5.0",
- "@jest/types": "^29.5.0",
- "@jridgewell/trace-mapping": "^0.3.15",
+ "@jest/console": "^29.6.4",
+ "@jest/test-result": "^29.6.4",
+ "@jest/transform": "^29.6.4",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
"@types/node": "*",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
@@ -1095,13 +1110,13 @@
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
"istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-instrument": "^6.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.1.3",
- "jest-message-util": "^29.5.0",
- "jest-util": "^29.5.0",
- "jest-worker": "^29.5.0",
+ "jest-message-util": "^29.6.3",
+ "jest-util": "^29.6.3",
+ "jest-worker": "^29.6.4",
"slash": "^3.0.0",
"string-length": "^4.0.1",
"strip-ansi": "^6.0.0",
@@ -1119,48 +1134,53 @@
}
}
},
- "node_modules/@jest/reporters/node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
+ "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
"dev": true,
- "license": "MIT",
"peer": true,
- "engines": {
- "node": ">=6.0.0"
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@jest/reporters/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
+ "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz",
+ "integrity": "sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/@jest/schemas": {
- "version": "29.4.3",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
"dependencies": {
- "@sinclair/typebox": "^0.25.16"
+ "@sinclair/typebox": "^0.27.8"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/source-map": {
- "version": "29.4.3",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
+ "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.15",
+ "@jridgewell/trace-mapping": "^0.3.18",
"callsites": "^3.0.0",
"graceful-fs": "^4.2.9"
},
@@ -1168,39 +1188,26 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/@jest/source-map/node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jest/source-map/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
"node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@jest/test-result": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz",
+ "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/console": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
},
@@ -1209,14 +1216,15 @@
}
},
"node_modules/@jest/test-sequencer": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz",
+ "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/test-result": "^29.5.0",
+ "@jest/test-result": "^29.6.4",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.5.0",
+ "jest-haste-map": "^29.6.4",
"slash": "^3.0.0"
},
"engines": {
@@ -1224,20 +1232,21 @@
}
},
"node_modules/@jest/transform": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz",
+ "integrity": "sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==",
"dependencies": {
"@babel/core": "^7.11.6",
- "@jest/types": "^29.5.0",
- "@jridgewell/trace-mapping": "^0.3.15",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
"babel-plugin-istanbul": "^6.1.1",
"chalk": "^4.0.0",
"convert-source-map": "^2.0.0",
"fast-json-stable-stringify": "^2.1.0",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.5.0",
- "jest-regex-util": "^29.4.3",
- "jest-util": "^29.5.0",
+ "jest-haste-map": "^29.6.4",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.6.3",
"micromatch": "^4.0.4",
"pirates": "^4.0.4",
"slash": "^3.0.0",
@@ -1267,10 +1276,11 @@
}
},
"node_modules/@jest/types": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
"dependencies": {
- "@jest/schemas": "^29.4.3",
+ "@jest/schemas": "^29.6.3",
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
@@ -1780,7 +1790,8 @@
},
"node_modules/@nestjs/testing": {
"version": "9.4.3",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.3.tgz",
+ "integrity": "sha512-LDT8Ai2eKnTzvnPaJwWOK03qTaFap5uHHsJCv6dL0uKWk6hyF9jms8DjyVaGsaujCaXDG8izl1mDEER0OmxaZA==",
"dependencies": {
"tslib": "2.5.3"
},
@@ -2431,65 +2442,6 @@
"node": ">=16"
}
},
- "node_modules/@redis/bloom": {
- "version": "1.2.0",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/client": {
- "version": "1.5.8",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "cluster-key-slot": "1.1.2",
- "generic-pool": "3.9.0",
- "yallist": "4.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@redis/graph": {
- "version": "1.1.0",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/json": {
- "version": "1.0.4",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/search": {
- "version": "1.1.3",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/time-series": {
- "version": "1.0.4",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
"node_modules/@scure/base": {
"version": "1.1.1",
"funding": [
@@ -2516,8 +2468,9 @@
"license": "BSD-3-Clause"
},
"node_modules/@sinclair/typebox": {
- "version": "0.25.24",
- "license": "MIT"
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="
},
"node_modules/@sindresorhus/is": {
"version": "5.4.1",
@@ -2532,21 +2485,24 @@
},
"node_modules/@sinonjs/commons": {
"version": "3.0.0",
- "license": "BSD-3-Clause",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
+ "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
"dependencies": {
"type-detect": "4.0.8"
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "10.1.0",
- "license": "BSD-3-Clause",
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
"dependencies": {
"@sinonjs/commons": "^3.0.0"
}
},
"node_modules/@sqltools/formatter": {
"version": "1.2.5",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz",
+ "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==",
"peer": true
},
"node_modules/@substrate/connect": {
@@ -2606,8 +2562,9 @@
},
"node_modules/@types/babel__core": {
"version": "7.20.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz",
+ "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.20.7",
@@ -2619,8 +2576,9 @@
},
"node_modules/@types/babel__generator": {
"version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.0.0"
@@ -2628,8 +2586,9 @@
},
"node_modules/@types/babel__template": {
"version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.1.0",
@@ -2638,7 +2597,10 @@
},
"node_modules/@types/babel__traverse": {
"version": "7.20.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz",
+ "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==",
+ "dev": true,
+ "peer": true,
"dependencies": {
"@babel/types": "^7.20.7"
}
@@ -2667,6 +2629,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/cookiejar": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz",
+ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==",
+ "dev": true
+ },
"node_modules/@types/eslint": {
"version": "8.44.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz",
@@ -2714,7 +2682,8 @@
},
"node_modules/@types/graceful-fs": {
"version": "4.1.6",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+ "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
"dependencies": {
"@types/node": "*"
}
@@ -2779,18 +2748,15 @@
}
},
"node_modules/@types/node": {
- "version": "20.2.5",
- "license": "MIT"
+ "version": "20.5.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz",
+ "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA=="
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
- "node_modules/@types/prettier": {
- "version": "2.7.3",
- "license": "MIT"
- },
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@@ -2802,9 +2768,10 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
"node_modules/@types/semver": {
- "version": "7.5.0",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/@types/send": {
@@ -2840,6 +2807,25 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/superagent": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.18.tgz",
+ "integrity": "sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==",
+ "dev": true,
+ "dependencies": {
+ "@types/cookiejar": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/supertest": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz",
+ "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/superagent": "*"
+ }
+ },
"node_modules/@types/time-constants": {
"version": "1.0.0",
"dev": true,
@@ -2866,17 +2852,18 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
+ "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
- "@typescript-eslint/scope-manager": "5.59.11",
- "@typescript-eslint/type-utils": "5.59.11",
- "@typescript-eslint/utils": "5.59.11",
+ "@typescript-eslint/scope-manager": "5.62.0",
+ "@typescript-eslint/type-utils": "5.62.0",
+ "@typescript-eslint/utils": "5.62.0",
"debug": "^4.3.4",
- "grapheme-splitter": "^1.0.4",
+ "graphemer": "^1.4.0",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
"semver": "^7.3.7",
@@ -2900,13 +2887,14 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+ "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
- "@typescript-eslint/visitor-keys": "5.59.11"
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2917,9 +2905,10 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+ "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2930,12 +2919,13 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+ "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/types": "5.62.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3015,13 +3005,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
+ "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.59.11",
- "@typescript-eslint/utils": "5.59.11",
+ "@typescript-eslint/typescript-estree": "5.62.0",
+ "@typescript-eslint/utils": "5.62.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -3042,9 +3033,10 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+ "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3055,13 +3047,14 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+ "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
"dev": true,
- "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
- "@typescript-eslint/visitor-keys": "5.59.11",
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -3082,12 +3075,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+ "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/types": "5.62.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3165,17 +3159,18 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
+ "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.59.11",
- "@typescript-eslint/types": "5.59.11",
- "@typescript-eslint/typescript-estree": "5.59.11",
+ "@typescript-eslint/scope-manager": "5.62.0",
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/typescript-estree": "5.62.0",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@@ -3191,13 +3186,14 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+ "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
- "@typescript-eslint/visitor-keys": "5.59.11"
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3208,9 +3204,10 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+ "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3221,13 +3218,14 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+ "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
"dev": true,
- "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
- "@typescript-eslint/visitor-keys": "5.59.11",
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -3248,12 +3246,13 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.59.11",
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+ "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/types": "5.62.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3577,7 +3576,8 @@
},
"node_modules/any-promise": {
"version": "1.3.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
"peer": true
},
"node_modules/anymatch": {
@@ -3593,7 +3593,8 @@
},
"node_modules/app-root-path": {
"version": "3.1.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
+ "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
"peer": true,
"engines": {
"node": ">= 6.0.0"
@@ -3693,11 +3694,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/async": {
- "version": "3.2.3",
- "license": "MIT",
- "optional": true,
- "peer": true
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true
},
"node_modules/asynckit": {
"version": "0.4.0",
@@ -3724,15 +3725,16 @@
}
},
"node_modules/babel-jest": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz",
+ "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/transform": "^29.5.0",
+ "@jest/transform": "^29.6.4",
"@types/babel__core": "^7.1.14",
"babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^29.5.0",
+ "babel-preset-jest": "^29.6.3",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"slash": "^3.0.0"
@@ -3759,9 +3761,10 @@
}
},
"node_modules/babel-plugin-jest-hoist": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@babel/template": "^7.3.3",
@@ -3795,12 +3798,13 @@
}
},
"node_modules/babel-preset-jest": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "babel-plugin-jest-hoist": "^29.5.0",
+ "babel-plugin-jest-hoist": "^29.6.3",
"babel-preset-current-node-syntax": "^1.0.0"
},
"engines": {
@@ -4002,13 +4006,16 @@
},
"node_modules/bser": {
"version": "2.1.1",
- "license": "Apache-2.0",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
"dependencies": {
"node-int64": "^0.4.0"
}
},
"node_modules/buffer": {
"version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
@@ -4023,7 +4030,6 @@
"url": "https://feross.org/support"
}
],
- "license": "MIT",
"peer": true,
"dependencies": {
"base64-js": "^1.3.1",
@@ -4120,26 +4126,6 @@
"node": ">= 0.8"
}
},
- "node_modules/cache-manager": {
- "version": "4.1.0",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "async": "3.2.3",
- "lodash.clonedeep": "^4.5.0",
- "lru-cache": "^7.10.1"
- }
- },
- "node_modules/cache-manager/node_modules/lru-cache": {
- "version": "7.18.3",
- "license": "ISC",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/cacheable-lookup": {
"version": "7.0.0",
"dev": true,
@@ -4224,8 +4210,9 @@
},
"node_modules/char-regex": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -4294,8 +4281,9 @@
},
"node_modules/cjs-module-lexer": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
+ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/class-transformer": {
@@ -4324,7 +4312,8 @@
},
"node_modules/cli-highlight": {
"version": "2.1.11",
- "license": "ISC",
+ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz",
+ "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==",
"peer": true,
"dependencies": {
"chalk": "^4.0.0",
@@ -4344,7 +4333,8 @@
},
"node_modules/cli-highlight/node_modules/cliui": {
"version": "7.0.4",
- "license": "ISC",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"peer": true,
"dependencies": {
"string-width": "^4.2.0",
@@ -4354,7 +4344,8 @@
},
"node_modules/cli-highlight/node_modules/yargs": {
"version": "16.2.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"peer": true,
"dependencies": {
"cliui": "^7.0.2",
@@ -4371,7 +4362,8 @@
},
"node_modules/cli-highlight/node_modules/yargs-parser": {
"version": "20.2.9",
- "license": "ISC",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"peer": true,
"engines": {
"node": ">=10"
@@ -4439,8 +4431,9 @@
},
"node_modules/co": {
"version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"iojs": ">= 1.0.0",
@@ -4448,9 +4441,10 @@
}
},
"node_modules/collect-v8-coverage": {
- "version": "1.0.1",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/color-convert": {
@@ -4500,6 +4494,12 @@
"node": ">= 6"
}
},
+ "node_modules/component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"license": "MIT"
@@ -4558,6 +4558,12 @@
"version": "1.0.6",
"license": "MIT"
},
+ "node_modules/cookiejar": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
+ "dev": true
+ },
"node_modules/core-util-is": {
"version": "1.0.3",
"license": "MIT"
@@ -4631,7 +4637,8 @@
},
"node_modules/date-fns": {
"version": "2.30.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+ "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.21.0"
@@ -4685,10 +4692,19 @@
}
},
"node_modules/dedent": {
- "version": "0.7.0",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
+ "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==",
"dev": true,
- "license": "MIT",
- "peer": true
+ "peer": true,
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
},
"node_modules/deep-extend": {
"version": "0.6.0",
@@ -4818,13 +4834,24 @@
},
"node_modules/detect-newline": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
},
+ "node_modules/dezalgo": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "dev": true,
+ "dependencies": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
+ },
"node_modules/diff": {
"version": "4.0.2",
"devOptional": true,
@@ -4834,8 +4861,9 @@
}
},
"node_modules/diff-sequences": {
- "version": "29.4.3",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
@@ -4897,8 +4925,9 @@
},
"node_modules/emittery": {
"version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
@@ -5421,20 +5450,29 @@
"license": "0BSD"
},
"node_modules/eslint-plugin-prettier": {
- "version": "4.2.1",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz",
+ "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "prettier-linter-helpers": "^1.0.0"
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.8.5"
},
"engines": {
- "node": ">=12.0.0"
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/prettier"
},
"peerDependencies": {
- "eslint": ">=7.28.0",
- "prettier": ">=2.0.0"
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
"eslint-config-prettier": {
"optional": true
}
@@ -5646,6 +5684,8 @@
},
"node_modules/exit": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
"dev": true,
"peer": true,
"engines": {
@@ -5653,14 +5693,15 @@
}
},
"node_modules/expect": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz",
+ "integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==",
"dependencies": {
- "@jest/expect-utils": "^29.5.0",
- "jest-get-type": "^29.4.3",
- "jest-matcher-utils": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-util": "^29.5.0"
+ "@jest/expect-utils": "^29.6.4",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.6.4",
+ "jest-message-util": "^29.6.3",
+ "jest-util": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -5827,7 +5868,8 @@
},
"node_modules/fb-watchman": {
"version": "2.0.2",
- "license": "Apache-2.0",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
"dependencies": {
"bser": "2.1.1"
}
@@ -6038,6 +6080,21 @@
"node": ">=12.20.0"
}
},
+ "node_modules/formidable": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
+ "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
+ "dev": true,
+ "dependencies": {
+ "dezalgo": "^1.0.4",
+ "hexoid": "^1.0.0",
+ "once": "^1.4.0",
+ "qs": "^6.11.0"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/tunnckoCore/commissions"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"license": "MIT",
@@ -6074,6 +6131,19 @@
"version": "1.0.0",
"license": "ISC"
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.1",
"license": "MIT"
@@ -6103,15 +6173,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/generic-pool": {
- "version": "3.9.0",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "engines": {
- "node": ">= 4"
- }
- },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"license": "MIT",
@@ -6311,12 +6372,6 @@
"version": "4.2.11",
"license": "ISC"
},
- "node_modules/grapheme-splitter": {
- "version": "1.0.4",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
"node_modules/graphemer": {
"version": "1.4.0",
"dev": true,
@@ -6420,9 +6475,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/hexoid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
+ "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/highlight.js": {
"version": "10.7.3",
- "license": "BSD-3-Clause",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
"peer": true,
"engines": {
"node": "*"
@@ -6430,8 +6495,9 @@
},
"node_modules/html-escaper": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/http-cache-semantics": {
@@ -6525,8 +6591,9 @@
},
"node_modules/import-local": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"pkg-dir": "^4.2.0",
@@ -6772,8 +6839,9 @@
},
"node_modules/is-generator-fn": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7021,23 +7089,25 @@
}
},
"node_modules/istanbul-lib-report": {
- "version": "3.0.0",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
- "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^3.0.0",
+ "make-dir": "^4.0.0",
"supports-color": "^7.1.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
}
},
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
"dev": true,
- "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"debug": "^4.1.1",
@@ -7049,9 +7119,10 @@
}
},
"node_modules/istanbul-reports": {
- "version": "3.1.5",
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
+ "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
"dev": true,
- "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"html-escaper": "^2.0.0",
@@ -7069,15 +7140,16 @@
}
},
"node_modules/jest": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz",
+ "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/core": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/core": "^29.6.4",
+ "@jest/types": "^29.6.3",
"import-local": "^3.0.2",
- "jest-cli": "^29.5.0"
+ "jest-cli": "^29.6.4"
},
"bin": {
"jest": "bin/jest.js"
@@ -7095,12 +7167,14 @@
}
},
"node_modules/jest-changed-files": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz",
+ "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"execa": "^5.0.0",
+ "jest-util": "^29.6.3",
"p-limit": "^3.1.0"
},
"engines": {
@@ -7109,8 +7183,9 @@
},
"node_modules/jest-changed-files/node_modules/execa": {
"version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -7132,8 +7207,9 @@
},
"node_modules/jest-changed-files/node_modules/human-signals": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
- "license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=10.17.0"
@@ -7141,8 +7217,9 @@
},
"node_modules/jest-changed-files/node_modules/is-stream": {
"version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -7153,8 +7230,9 @@
},
"node_modules/jest-changed-files/node_modules/mimic-fn": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7162,8 +7240,9 @@
},
"node_modules/jest-changed-files/node_modules/npm-run-path": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"path-key": "^3.0.0"
@@ -7174,8 +7253,9 @@
},
"node_modules/jest-changed-files/node_modules/onetime": {
"version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"mimic-fn": "^2.1.0"
@@ -7189,36 +7269,38 @@
},
"node_modules/jest-changed-files/node_modules/strip-final-newline": {
"version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
}
},
"node_modules/jest-circus": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz",
+ "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.5.0",
- "@jest/expect": "^29.5.0",
- "@jest/test-result": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/environment": "^29.6.4",
+ "@jest/expect": "^29.6.4",
+ "@jest/test-result": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "dedent": "^0.7.0",
+ "dedent": "^1.0.0",
"is-generator-fn": "^2.0.0",
- "jest-each": "^29.5.0",
- "jest-matcher-utils": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-runtime": "^29.5.0",
- "jest-snapshot": "^29.5.0",
- "jest-util": "^29.5.0",
+ "jest-each": "^29.6.3",
+ "jest-matcher-utils": "^29.6.4",
+ "jest-message-util": "^29.6.3",
+ "jest-runtime": "^29.6.4",
+ "jest-snapshot": "^29.6.4",
+ "jest-util": "^29.6.3",
"p-limit": "^3.1.0",
- "pretty-format": "^29.5.0",
+ "pretty-format": "^29.6.3",
"pure-rand": "^6.0.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
@@ -7228,21 +7310,22 @@
}
},
"node_modules/jest-cli": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz",
+ "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/core": "^29.5.0",
- "@jest/test-result": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/core": "^29.6.4",
+ "@jest/test-result": "^29.6.4",
+ "@jest/types": "^29.6.3",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.9",
"import-local": "^3.0.2",
- "jest-config": "^29.5.0",
- "jest-util": "^29.5.0",
- "jest-validate": "^29.5.0",
+ "jest-config": "^29.6.4",
+ "jest-util": "^29.6.3",
+ "jest-validate": "^29.6.3",
"prompts": "^2.0.1",
"yargs": "^17.3.1"
},
@@ -7262,31 +7345,32 @@
}
},
"node_modules/jest-config": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz",
+ "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^29.5.0",
- "@jest/types": "^29.5.0",
- "babel-jest": "^29.5.0",
+ "@jest/test-sequencer": "^29.6.4",
+ "@jest/types": "^29.6.3",
+ "babel-jest": "^29.6.4",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
- "jest-circus": "^29.5.0",
- "jest-environment-node": "^29.5.0",
- "jest-get-type": "^29.4.3",
- "jest-regex-util": "^29.4.3",
- "jest-resolve": "^29.5.0",
- "jest-runner": "^29.5.0",
- "jest-util": "^29.5.0",
- "jest-validate": "^29.5.0",
+ "jest-circus": "^29.6.4",
+ "jest-environment-node": "^29.6.4",
+ "jest-get-type": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.6.4",
+ "jest-runner": "^29.6.4",
+ "jest-util": "^29.6.3",
+ "jest-validate": "^29.6.3",
"micromatch": "^4.0.4",
"parse-json": "^5.2.0",
- "pretty-format": "^29.5.0",
+ "pretty-format": "^29.6.3",
"slash": "^3.0.0",
"strip-json-comments": "^3.1.1"
},
@@ -7307,22 +7391,24 @@
}
},
"node_modules/jest-diff": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz",
+ "integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==",
"dependencies": {
"chalk": "^4.0.0",
- "diff-sequences": "^29.4.3",
- "jest-get-type": "^29.4.3",
- "pretty-format": "^29.5.0"
+ "diff-sequences": "^29.6.3",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-docblock": {
- "version": "29.4.3",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz",
+ "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"detect-newline": "^3.0.0"
@@ -7332,58 +7418,62 @@
}
},
"node_modules/jest-each": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz",
+ "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"chalk": "^4.0.0",
- "jest-get-type": "^29.4.3",
- "jest-util": "^29.5.0",
- "pretty-format": "^29.5.0"
+ "jest-get-type": "^29.6.3",
+ "jest-util": "^29.6.3",
+ "pretty-format": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-environment-node": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz",
+ "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.5.0",
- "@jest/fake-timers": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/environment": "^29.6.4",
+ "@jest/fake-timers": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
- "jest-mock": "^29.5.0",
- "jest-util": "^29.5.0"
+ "jest-mock": "^29.6.3",
+ "jest-util": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-get-type": {
- "version": "29.4.3",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
+ "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-haste-map": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz",
+ "integrity": "sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==",
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@types/graceful-fs": "^4.1.3",
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"graceful-fs": "^4.2.9",
- "jest-regex-util": "^29.4.3",
- "jest-util": "^29.5.0",
- "jest-worker": "^29.5.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.6.3",
+ "jest-worker": "^29.6.4",
"micromatch": "^4.0.4",
"walker": "^1.0.8"
},
@@ -7395,42 +7485,45 @@
}
},
"node_modules/jest-leak-detector": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz",
+ "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "jest-get-type": "^29.4.3",
- "pretty-format": "^29.5.0"
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-matcher-utils": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz",
+ "integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==",
"dependencies": {
"chalk": "^4.0.0",
- "jest-diff": "^29.5.0",
- "jest-get-type": "^29.4.3",
- "pretty-format": "^29.5.0"
+ "jest-diff": "^29.6.4",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-message-util": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz",
+ "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==",
"dependencies": {
"@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"micromatch": "^4.0.4",
- "pretty-format": "^29.5.0",
+ "pretty-format": "^29.6.3",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
},
@@ -7439,12 +7532,13 @@
}
},
"node_modules/jest-mock": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz",
+ "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==",
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
- "jest-util": "^29.5.0"
+ "jest-util": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7452,8 +7546,9 @@
},
"node_modules/jest-pnp-resolver": {
"version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7468,24 +7563,26 @@
}
},
"node_modules/jest-regex-util": {
- "version": "29.4.3",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
+ "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-resolve": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz",
+ "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.5.0",
+ "jest-haste-map": "^29.6.4",
"jest-pnp-resolver": "^1.2.2",
- "jest-util": "^29.5.0",
- "jest-validate": "^29.5.0",
+ "jest-util": "^29.6.3",
+ "jest-validate": "^29.6.3",
"resolve": "^1.20.0",
"resolve.exports": "^2.0.0",
"slash": "^3.0.0"
@@ -7495,43 +7592,45 @@
}
},
"node_modules/jest-resolve-dependencies": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz",
+ "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "jest-regex-util": "^29.4.3",
- "jest-snapshot": "^29.5.0"
+ "jest-regex-util": "^29.6.3",
+ "jest-snapshot": "^29.6.4"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-runner": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz",
+ "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.5.0",
- "@jest/environment": "^29.5.0",
- "@jest/test-result": "^29.5.0",
- "@jest/transform": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/console": "^29.6.4",
+ "@jest/environment": "^29.6.4",
+ "@jest/test-result": "^29.6.4",
+ "@jest/transform": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"chalk": "^4.0.0",
"emittery": "^0.13.1",
"graceful-fs": "^4.2.9",
- "jest-docblock": "^29.4.3",
- "jest-environment-node": "^29.5.0",
- "jest-haste-map": "^29.5.0",
- "jest-leak-detector": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-resolve": "^29.5.0",
- "jest-runtime": "^29.5.0",
- "jest-util": "^29.5.0",
- "jest-watcher": "^29.5.0",
- "jest-worker": "^29.5.0",
+ "jest-docblock": "^29.6.3",
+ "jest-environment-node": "^29.6.4",
+ "jest-haste-map": "^29.6.4",
+ "jest-leak-detector": "^29.6.3",
+ "jest-message-util": "^29.6.3",
+ "jest-resolve": "^29.6.4",
+ "jest-runtime": "^29.6.4",
+ "jest-util": "^29.6.3",
+ "jest-watcher": "^29.6.4",
+ "jest-worker": "^29.6.4",
"p-limit": "^3.1.0",
"source-map-support": "0.5.13"
},
@@ -7541,8 +7640,9 @@
},
"node_modules/jest-runner/node_modules/source-map-support": {
"version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
@@ -7550,31 +7650,32 @@
}
},
"node_modules/jest-runtime": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz",
+ "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.5.0",
- "@jest/fake-timers": "^29.5.0",
- "@jest/globals": "^29.5.0",
- "@jest/source-map": "^29.4.3",
- "@jest/test-result": "^29.5.0",
- "@jest/transform": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/environment": "^29.6.4",
+ "@jest/fake-timers": "^29.6.4",
+ "@jest/globals": "^29.6.4",
+ "@jest/source-map": "^29.6.3",
+ "@jest/test-result": "^29.6.4",
+ "@jest/transform": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"chalk": "^4.0.0",
"cjs-module-lexer": "^1.0.0",
"collect-v8-coverage": "^1.0.0",
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-mock": "^29.5.0",
- "jest-regex-util": "^29.4.3",
- "jest-resolve": "^29.5.0",
- "jest-snapshot": "^29.5.0",
- "jest-util": "^29.5.0",
+ "jest-haste-map": "^29.6.4",
+ "jest-message-util": "^29.6.3",
+ "jest-mock": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.6.4",
+ "jest-snapshot": "^29.6.4",
+ "jest-util": "^29.6.3",
"slash": "^3.0.0",
"strip-bom": "^4.0.0"
},
@@ -7584,50 +7685,50 @@
},
"node_modules/jest-runtime/node_modules/strip-bom": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
},
"node_modules/jest-snapshot": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz",
+ "integrity": "sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==",
"dependencies": {
"@babel/core": "^7.11.6",
"@babel/generator": "^7.7.2",
"@babel/plugin-syntax-jsx": "^7.7.2",
"@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/traverse": "^7.7.2",
"@babel/types": "^7.3.3",
- "@jest/expect-utils": "^29.5.0",
- "@jest/transform": "^29.5.0",
- "@jest/types": "^29.5.0",
- "@types/babel__traverse": "^7.0.6",
- "@types/prettier": "^2.1.5",
+ "@jest/expect-utils": "^29.6.4",
+ "@jest/transform": "^29.6.4",
+ "@jest/types": "^29.6.3",
"babel-preset-current-node-syntax": "^1.0.0",
"chalk": "^4.0.0",
- "expect": "^29.5.0",
+ "expect": "^29.6.4",
"graceful-fs": "^4.2.9",
- "jest-diff": "^29.5.0",
- "jest-get-type": "^29.4.3",
- "jest-matcher-utils": "^29.5.0",
- "jest-message-util": "^29.5.0",
- "jest-util": "^29.5.0",
+ "jest-diff": "^29.6.4",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.6.4",
+ "jest-message-util": "^29.6.3",
+ "jest-util": "^29.6.3",
"natural-compare": "^1.4.0",
- "pretty-format": "^29.5.0",
- "semver": "^7.3.5"
+ "pretty-format": "^29.6.3",
+ "semver": "^7.5.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-util": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz",
+ "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==",
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
@@ -7639,17 +7740,18 @@
}
},
"node_modules/jest-validate": {
- "version": "29.5.0",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz",
+ "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.5.0",
+ "@jest/types": "^29.6.3",
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
- "jest-get-type": "^29.4.3",
+ "jest-get-type": "^29.6.3",
"leven": "^3.1.0",
- "pretty-format": "^29.5.0"
+ "pretty-format": "^29.6.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7657,8 +7759,9 @@
},
"node_modules/jest-validate/node_modules/camelcase": {
"version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -7668,18 +7771,19 @@
}
},
"node_modules/jest-watcher": {
- "version": "29.5.0",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz",
+ "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/test-result": "^29.5.0",
- "@jest/types": "^29.5.0",
+ "@jest/test-result": "^29.6.4",
+ "@jest/types": "^29.6.3",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"emittery": "^0.13.1",
- "jest-util": "^29.5.0",
+ "jest-util": "^29.6.3",
"string-length": "^4.0.1"
},
"engines": {
@@ -7687,11 +7791,12 @@
}
},
"node_modules/jest-worker": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.4",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz",
+ "integrity": "sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==",
"dependencies": {
"@types/node": "*",
- "jest-util": "^29.5.0",
+ "jest-util": "^29.6.3",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
},
@@ -7701,7 +7806,8 @@
},
"node_modules/jest-worker/node_modules/supports-color": {
"version": "8.1.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -7805,8 +7911,9 @@
},
"node_modules/kleur": {
"version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7814,8 +7921,9 @@
},
"node_modules/leven": {
"version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7889,12 +7997,6 @@
"version": "4.17.21",
"license": "MIT"
},
- "node_modules/lodash.clonedeep": {
- "version": "4.5.0",
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/lodash.defaults": {
"version": "4.2.0",
"license": "MIT"
@@ -7987,29 +8089,21 @@
}
},
"node_modules/make-dir": {
- "version": "3.1.0",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "semver": "^6.0.0"
+ "semver": "^7.5.3"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/make-dir/node_modules/semver": {
- "version": "6.3.1",
- "dev": true,
- "license": "ISC",
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/make-error": {
"version": "1.3.6",
"devOptional": true,
@@ -8017,7 +8111,8 @@
},
"node_modules/makeerror": {
"version": "1.0.12",
- "license": "BSD-3-Clause",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
"dependencies": {
"tmpl": "1.0.5"
}
@@ -8219,7 +8314,8 @@
},
"node_modules/mz": {
"version": "2.7.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
"peer": true,
"dependencies": {
"any-promise": "^1.0.0",
@@ -8233,8 +8329,9 @@
},
"node_modules/natural-compare-lite": {
"version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/negotiator": {
@@ -8328,7 +8425,8 @@
},
"node_modules/node-int64": {
"version": "0.4.0",
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="
},
"node_modules/node-releases": {
"version": "2.0.12",
@@ -8630,12 +8728,14 @@
},
"node_modules/parse5": {
"version": "5.1.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
"peer": true
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
"peer": true,
"dependencies": {
"parse5": "^6.0.1"
@@ -8643,7 +8743,8 @@
},
"node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
"version": "6.0.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"peer": true
},
"node_modules/parseurl": {
@@ -8743,8 +8844,9 @@
},
"node_modules/pkg-dir": {
"version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"find-up": "^4.0.0"
@@ -8755,8 +8857,9 @@
},
"node_modules/pkg-dir/node_modules/find-up": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"locate-path": "^5.0.0",
@@ -8768,8 +8871,9 @@
},
"node_modules/pkg-dir/node_modules/locate-path": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"p-locate": "^4.1.0"
@@ -8780,8 +8884,9 @@
},
"node_modules/pkg-dir/node_modules/p-limit": {
"version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"p-try": "^2.0.0"
@@ -8795,8 +8900,9 @@
},
"node_modules/pkg-dir/node_modules/p-locate": {
"version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"p-limit": "^2.2.0"
@@ -8822,15 +8928,16 @@
}
},
"node_modules/prettier": {
- "version": "2.8.8",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz",
+ "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"bin": {
- "prettier": "bin-prettier.js"
+ "prettier": "bin/prettier.cjs"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -8848,10 +8955,11 @@
}
},
"node_modules/pretty-format": {
- "version": "29.5.0",
- "license": "MIT",
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz",
+ "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==",
"dependencies": {
- "@jest/schemas": "^29.4.3",
+ "@jest/schemas": "^29.6.3",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
},
@@ -8875,8 +8983,9 @@
},
"node_modules/prompts": {
"version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"kleur": "^3.0.3",
@@ -8926,6 +9035,8 @@
},
"node_modules/pure-rand": {
"version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz",
+ "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==",
"dev": true,
"funding": [
{
@@ -8937,7 +9048,6 @@
"url": "https://opencollective.com/fast-check"
}
],
- "license": "MIT",
"peer": true
},
"node_modules/qs": {
@@ -9075,23 +9185,6 @@
"node": ">= 0.10"
}
},
- "node_modules/redis": {
- "version": "4.6.7",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "workspaces": [
- "./packages/*"
- ],
- "dependencies": {
- "@redis/bloom": "1.2.0",
- "@redis/client": "1.5.8",
- "@redis/graph": "1.1.0",
- "@redis/json": "1.0.4",
- "@redis/search": "1.1.3",
- "@redis/time-series": "1.0.4"
- }
- },
"node_modules/redis-errors": {
"version": "1.2.0",
"license": "MIT",
@@ -9111,12 +9204,14 @@
},
"node_modules/reflect-metadata": {
"version": "0.1.13",
- "license": "Apache-2.0",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
"peer": true
},
"node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "license": "MIT",
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
"peer": true
},
"node_modules/regexp.prototype.flags": {
@@ -9191,8 +9286,9 @@
},
"node_modules/resolve-cwd": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"resolve-from": "^5.0.0"
@@ -9203,8 +9299,9 @@
},
"node_modules/resolve-cwd/node_modules/resolve-from": {
"version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -9227,8 +9324,9 @@
},
"node_modules/resolve.exports": {
"version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
+ "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
"dev": true,
- "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -9492,8 +9590,9 @@
}
},
"node_modules/semver": {
- "version": "7.5.3",
- "license": "ISC",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -9578,7 +9677,8 @@
},
"node_modules/sha.js": {
"version": "2.4.11",
- "license": "(MIT AND BSD-3-Clause)",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"peer": true,
"dependencies": {
"inherits": "^2.0.1",
@@ -9639,8 +9739,9 @@
},
"node_modules/sisteransi": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/slash": {
@@ -9737,8 +9838,9 @@
},
"node_modules/string-length": {
"version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
"char-regex": "^1.0.2",
@@ -9841,6 +9943,52 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/superagent": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz",
+ "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
+ "dev": true,
+ "dependencies": {
+ "component-emitter": "^1.3.0",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.4",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.0",
+ "formidable": "^2.1.2",
+ "methods": "^1.1.2",
+ "mime": "2.6.0",
+ "qs": "^6.11.0",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=6.4.0 <13 || >=14"
+ }
+ },
+ "node_modules/superagent/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/supertest": {
+ "version": "6.3.3",
+ "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz",
+ "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==",
+ "dev": true,
+ "dependencies": {
+ "methods": "^1.1.2",
+ "superagent": "^8.0.5"
+ },
+ "engines": {
+ "node": ">=6.4.0"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"license": "MIT",
@@ -10018,7 +10166,8 @@
},
"node_modules/thenify": {
"version": "3.3.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
"peer": true,
"dependencies": {
"any-promise": "^1.0.0"
@@ -10026,7 +10175,8 @@
},
"node_modules/thenify-all": {
"version": "1.6.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"peer": true,
"dependencies": {
"thenify": ">= 3.1.0 < 4"
@@ -10068,7 +10218,8 @@
},
"node_modules/tmpl": {
"version": "1.0.5",
- "license": "BSD-3-Clause"
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
@@ -10147,6 +10298,25 @@
}
}
},
+ "node_modules/ts-loader": {
+ "version": "9.4.4",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz",
+ "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "enhanced-resolve": "^5.0.0",
+ "micromatch": "^4.0.0",
+ "semver": "^7.3.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "typescript": "*",
+ "webpack": "^5.0.0"
+ }
+ },
"node_modules/ts-node": {
"version": "10.9.1",
"devOptional": true,
@@ -10324,7 +10494,8 @@
},
"node_modules/type-detect": {
"version": "4.0.8",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"engines": {
"node": ">=4"
}
@@ -10369,8 +10540,9 @@
"license": "MIT"
},
"node_modules/typeorm": {
- "version": "0.3.16",
- "license": "MIT",
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz",
+ "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==",
"peer": true,
"dependencies": {
"@sqltools/formatter": "^1.2.5",
@@ -10475,7 +10647,8 @@
},
"node_modules/typeorm/node_modules/brace-expansion": {
"version": "2.0.1",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"peer": true,
"dependencies": {
"balanced-match": "^1.0.0"
@@ -10483,7 +10656,8 @@
},
"node_modules/typeorm/node_modules/glob": {
"version": "8.1.0",
- "license": "ISC",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"peer": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -10501,7 +10675,8 @@
},
"node_modules/typeorm/node_modules/minimatch": {
"version": "5.1.6",
- "license": "ISC",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"peer": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -10512,7 +10687,8 @@
},
"node_modules/typeorm/node_modules/mkdirp": {
"version": "2.1.6",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
+ "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
"peer": true,
"bin": {
"mkdirp": "dist/cjs/src/bin.js"
@@ -10664,8 +10840,9 @@
},
"node_modules/v8-to-istanbul": {
"version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
+ "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
"dev": true,
- "license": "ISC",
"peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
@@ -10676,35 +10853,22 @@
"node": ">=10.12.0"
}
},
- "node_modules/v8-to-istanbul/node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/v8-to-istanbul/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
"node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
"dev": true,
- "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/v8-to-istanbul/node_modules/convert-source-map": {
"version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true,
- "license": "MIT",
"peer": true
},
"node_modules/validator": {
@@ -10728,7 +10892,8 @@
},
"node_modules/walker": {
"version": "1.0.8",
- "license": "Apache-2.0",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
"dependencies": {
"makeerror": "1.0.12"
}
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 38f9869f..4de7f2fc 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -17,7 +17,8 @@
"clean": "rm -Rf dist",
"lint": "tsc --noEmit --pretty && eslint \"**/*.ts\" --fix",
"pretest": "cp env.template .env",
- "test": "jest --coverage --verbose"
+ "test": "jest --coverage --verbose",
+ "test:e2e": "jest --config ./apps/api/test/jest-e2e.json --detectOpenHandles"
},
"repository": {
"type": "git",
@@ -36,9 +37,9 @@
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
"@nestjs/bullmq": "^10.0.0",
+ "@nestjs/cli": "^10.1.14",
"@nestjs/common": "^9.4.0",
"@nestjs/config": "^2.3.1",
- "@nestjs/cli": "^10.1.14",
"@nestjs/core": "^9.4.0",
"@nestjs/event-emitter": "^1.4.1",
"@nestjs/platform-express": "^9.4.0",
@@ -65,8 +66,11 @@
},
"devDependencies": {
"@polkadot/typegen": "10.9.1",
+ "@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
+ "@types/supertest": "^2.0.12",
"@types/time-constants": "^1.0.0",
+ "@types/node": "^20.3.1",
"@typescript-eslint/parser": "^5.59.8",
"@typescript-eslint/typescript-estree": "5.59.8",
"dotenv": "^16.3.1",
@@ -78,13 +82,45 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-nestjs": "^1.2.3",
- "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
"license-report": "^6.4.0",
+ "supertest": "^6.3.3",
+ "ts-loader": "^9.4.3",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
+ },
+ "jest": {
+ "moduleFileExtensions": [
+ "js",
+ "json",
+ "ts"
+ ],
+ "rootDir": ".",
+ "setupFiles": [
+ "dotenv/config"
+ ],
+ "testRegex": ".*\\.spec\\.ts$",
+ "testPathIgnorePatterns": [
+ ".*\\.mock\\.spec\\.ts$"
+ ],
+ "transform": {
+ "^.+\\.(t|j)s$": "ts-jest"
+ },
+ "collectCoverageFrom": [
+ "**/*.(t|j)s"
+ ],
+ "coverageDirectory": "./coverage",
+ "testEnvironment": "node",
+ "roots": [
+ "/apps/",
+ "/libs/"
+ ],
+ "moduleNameMapper": {
+ "^@content-publishing-common(|/.*)$": "/libs/common/src/$1"
+ }
}
}
From 98b80b28bc5b4294cb479e057e028aef1f50acf5 Mon Sep 17 00:00:00 2001
From: Aramik
Date: Wed, 30 Aug 2023 09:24:15 -0700
Subject: [PATCH 008/137] enqueue requests (#25)
---
.../apps/api/src/api.controller.ts | 46 ++++++-----------
.../apps/api/src/api.module.ts | 13 ++++-
.../apps/api/src/api.service.ts | 36 +++++++++++++
.../apps/api/src/development.controller.ts | 16 ++++--
.../content-watcher/apps/api/src/metadata.ts | 2 +-
.../worker/src/publisher/publisher.module.ts | 3 +-
.../src/publisher/publishing.service.ts | 5 +-
.../libs/common/src/constants.ts | 32 ++----------
.../libs/common/src/dtos/activity.dto.ts | 2 +-
.../libs/common/src/dtos/announcement.dto.ts | 10 ++--
.../libs/common/src/dtos/common.dto.ts | 10 ++++
.../libs/common/src/dtos/validation.dto.ts | 32 ++++++++++++
.../content-watcher/libs/common/src/index.ts | 3 ++
.../src/interfaces/request-job.interface.ts | 10 ++++
.../libs/common/src/utils/queues.ts | 51 +++++++++++++++++++
services/content-watcher/package-lock.json | 7 +++
services/content-watcher/package.json | 7 +--
17 files changed, 206 insertions(+), 79 deletions(-)
create mode 100644 services/content-watcher/apps/api/src/api.service.ts
create mode 100644 services/content-watcher/libs/common/src/dtos/validation.dto.ts
create mode 100644 services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
create mode 100644 services/content-watcher/libs/common/src/utils/queues.ts
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index a32d30ac..12144e64 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -3,24 +3,26 @@ import { v4 as uuidv4 } from 'uuid';
import { FilesInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes } from '@nestjs/swagger';
import {
+ AnnouncementResponseDto,
+ AnnouncementTypeDto,
BroadcastDto,
+ DSNP_VALID_MIME_TYPES,
+ DsnpContentHashParam,
+ DsnpUserIdParam,
+ FilesUploadDto,
+ ProfileDto,
ReactionDto,
ReplyDto,
UpdateDto,
- ProfileDto,
- AnnouncementResponseDto,
- FilesUploadDto,
UploadResponseDto,
- DsnpUserIdParam,
- DsnpContentHashParam,
} from '../../../libs/common/src';
-import { DSNP_VALID_MIME_TYPES } from '../../../libs/common/src/constants';
+import { ApiService } from './api.service';
@Controller('api')
export class ApiController {
private readonly logger: Logger;
- constructor() {
+ constructor(private apiService: ApiService) {
this.logger = new Logger(this.constructor.name);
}
@@ -66,54 +68,36 @@ export class ApiController {
@Post('content/:userDsnpId/broadcast')
@HttpCode(202)
async broadcast(@Param() userDsnpId: DsnpUserIdParam, @Body() broadcastDto: BroadcastDto): Promise {
- this.logger.log(`broadcast ${userDsnpId}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.BROADCAST, userDsnpId.userDsnpId, broadcastDto);
}
@Post('content/:userDsnpId/reply')
@HttpCode(202)
async reply(@Param() userDsnpId: DsnpUserIdParam, @Body() replyDto: ReplyDto): Promise {
- this.logger.log(`reply ${userDsnpId}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.REPLY, userDsnpId.userDsnpId, replyDto);
}
@Post('content/:userDsnpId/reaction')
@HttpCode(202)
async reaction(@Param() userDsnpId: DsnpUserIdParam, @Body() reactionDto: ReactionDto): Promise {
- this.logger.log(`reaction ${userDsnpId}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.REACTION, userDsnpId.userDsnpId, reactionDto);
}
@Put('content/:userDsnpId/:targetContentHash')
@HttpCode(202)
async update(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam, @Body() updateDto: UpdateDto): Promise {
- this.logger.log(`update ${userDsnpId}/${targetContentHash}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto, targetContentHash.targetContentHash);
}
@Delete('content/:userDsnpId/:targetContentHash')
@HttpCode(202)
async delete(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam): Promise {
- this.logger.log(`delete ${userDsnpId}/${targetContentHash}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.TOMBSTONE, userDsnpId.userDsnpId, undefined, targetContentHash.targetContentHash);
}
@Put('profile/:userDsnpId')
@HttpCode(202)
async profile(@Param() userDsnpId: DsnpUserIdParam, @Body() profileDto: ProfileDto): Promise {
- this.logger.log(`profile ${userDsnpId}`);
- return {
- referenceId: uuidv4(),
- };
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.PROFILE, userDsnpId.userDsnpId, profileDto);
}
}
diff --git a/services/content-watcher/apps/api/src/api.module.ts b/services/content-watcher/apps/api/src/api.module.ts
index 94100d93..b7f45e39 100644
--- a/services/content-watcher/apps/api/src/api.module.ts
+++ b/services/content-watcher/apps/api/src/api.module.ts
@@ -7,10 +7,19 @@ import { ApiController } from './api.controller';
import { ConfigService } from './config/config.service';
import { ConfigModule } from './config/config.module';
import { DevelopmentController } from './development.controller';
+import { QueueConstants } from '../../../libs/common/src';
+import { ApiService } from './api.service';
@Module({
imports: [
- BullModule,
+ BullModule.forRoot({
+ connection: {
+ enableOfflineQueue: false,
+ },
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.REQUEST_QUEUE_NAME,
+ }),
ConfigModule,
RedisModule.forRootAsync(
{
@@ -42,7 +51,7 @@ import { DevelopmentController } from './development.controller';
}),
ScheduleModule.forRoot(),
],
- providers: [ConfigService],
+ providers: [ConfigService, ApiService],
controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ApiController] : [ApiController],
exports: [],
})
diff --git a/services/content-watcher/apps/api/src/api.service.ts b/services/content-watcher/apps/api/src/api.service.ts
new file mode 100644
index 00000000..5ca051c4
--- /dev/null
+++ b/services/content-watcher/apps/api/src/api.service.ts
@@ -0,0 +1,36 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { InjectQueue } from '@nestjs/bullmq';
+import { Queue } from 'bullmq';
+import { createHash } from 'crypto';
+import { AnnouncementResponseDto, AnnouncementTypeDto, IRequestJob, QueueConstants, RequestTypeDto } from '../../../libs/common/src';
+
+@Injectable()
+export class ApiService {
+ private readonly logger: Logger;
+
+ constructor(@InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue) {
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ async enqueueRequest(announcementType: AnnouncementTypeDto, dsnpUserId: string, content?: RequestTypeDto, targetContentHash?: string): Promise {
+ const data = {
+ content,
+ id: '',
+ announcementType,
+ dsnpUserId,
+ targetContentHash,
+ } as IRequestJob;
+ data.id = this.calculateJobId(data);
+ const job = await this.requestQueue.add(`Request Job - ${data.id}`, data, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 }); // TODO: should come from config
+ this.logger.debug(job);
+ return {
+ referenceId: data.id,
+ };
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ calculateJobId(jobWithoutId: IRequestJob): string {
+ const stringVal = JSON.stringify(jobWithoutId);
+ return createHash('sha1').update(stringVal).digest('base64url');
+ }
+}
diff --git a/services/content-watcher/apps/api/src/development.controller.ts b/services/content-watcher/apps/api/src/development.controller.ts
index 5aed5f47..05ccdaec 100644
--- a/services/content-watcher/apps/api/src/development.controller.ts
+++ b/services/content-watcher/apps/api/src/development.controller.ts
@@ -4,18 +4,24 @@ To use it, simply rename and remove the '.dev' extension
*/
// eslint-disable-next-line max-classes-per-file
-import { Controller, Logger, Post, Body, Param, Query, HttpException, HttpStatus } from '@nestjs/common';
+import { Controller, Logger, Post, Body, Param, Query, HttpException, HttpStatus, Get } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
-import { plainToClass } from 'class-transformer';
-import { InjectRedis } from '@liaoliaots/nestjs-redis';
-import Redis from 'ioredis';
+import { QueueConstants } from '../../../libs/common/src';
@Controller('api/dev')
export class DevelopmentController {
private readonly logger: Logger;
- constructor() {
+ constructor(@InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue) {
this.logger = new Logger(this.constructor.name);
}
+
+ @Get('/request/:jobId')
+ async requestJob(@Param('jobId') jobId: string) {
+ this.logger.log(jobId);
+ const job = await this.requestQueue.getJob(jobId);
+ this.logger.log(job);
+ return job;
+ }
}
diff --git a/services/content-watcher/apps/api/src/metadata.ts b/services/content-watcher/apps/api/src/metadata.ts
index 71c2be77..9577d58d 100644
--- a/services/content-watcher/apps/api/src/metadata.ts
+++ b/services/content-watcher/apps/api/src/metadata.ts
@@ -5,5 +5,5 @@ export default async () => {
["../../../libs/common/src/dtos/announcement.dto"]: await import("../../../libs/common/src/dtos/announcement.dto"),
["../../../libs/common/src/dtos/common.dto"]: await import("../../../libs/common/src/dtos/common.dto")
};
- return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LocationDto": { name: { required: true, type: () => String, minLength: 1 }, accuracy: { required: false, type: () => Number, minimum: 0, maximum: 100 }, altitude: { required: false, type: () => Number }, latitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number, minimum: 0 }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String, minLength: 1 }, height: { required: false, type: () => Number, minimum: 1 }, width: { required: false, type: () => Number, minimum: 1 }, duration: { required: false, type: () => String, pattern: "DURATION_REGEX" } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String, minLength: 1 }, mentionedId: { required: false, type: () => String, minLength: 1, pattern: "DSNP_USER_URI_REGEX" } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String, minLength: 1 }, href: { required: false, type: () => String, minLength: 1 } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String, minLength: 1 }, published: { required: true, type: () => String, pattern: "ISO8601_REGEX" }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String, pattern: "ISO8601_REGEX" } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].AnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String, minLength: 1, pattern: "DSNP_EMOJI_REGEX" }, apply: { required: true, type: () => Number, minimum: 0, maximum: 255 }, inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "DsnpUserIdParam": { userDsnpId: { required: true, type: () => String } }, "DsnpContentHashParam": { targetContentHash: { required: true, type: () => String } }, "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }]] } };
+ return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LocationDto": { name: { required: true, type: () => String, minLength: 1 }, accuracy: { required: false, type: () => Number, minimum: 0, maximum: 100 }, altitude: { required: false, type: () => Number }, latitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number, minimum: 0 }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String, minLength: 1 }, height: { required: false, type: () => Number, minimum: 1 }, width: { required: false, type: () => Number, minimum: 1 }, duration: { required: false, type: () => String, pattern: "DURATION_REGEX" } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String, minLength: 1 }, mentionedId: { required: false, type: () => String, minLength: 1, pattern: "DSNP_USER_URI_REGEX" } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String, minLength: 1 }, href: { required: false, type: () => String, minLength: 1 } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String, minLength: 1 }, published: { required: true, type: () => String, pattern: "ISO8601_REGEX" }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String, pattern: "ISO8601_REGEX" } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].UpdateAnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String, minLength: 1, pattern: "DSNP_EMOJI_REGEX" }, apply: { required: true, type: () => Number, minimum: 0, maximum: 255 }, inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "DsnpUserIdParam": { userDsnpId: { required: true, type: () => String } }, "DsnpContentHashParam": { targetContentHash: { required: true, type: () => String } }, "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }], [import("./development.controller"), { "DevelopmentController": { "requestJob": {} } }]] } };
};
\ No newline at end of file
diff --git a/services/content-watcher/apps/worker/src/publisher/publisher.module.ts b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
index de3c7fde..583db9a3 100644
--- a/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
+++ b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
@@ -11,6 +11,7 @@ import { ConfigModule } from '../../../api/src/config/config.module';
import { ConfigService } from '../../../api/src/config/config.service';
import { BlockchainModule } from '../blockchain/blockchain.module';
import { IPFSPublisher } from './ipfs.publisher';
+import { QueueConstants } from '../../../../libs/common/src';
@Module({
imports: [
@@ -51,7 +52,7 @@ import { IPFSPublisher } from './ipfs.publisher';
inject: [ConfigService],
}),
BullModule.registerQueue({
- name: 'publishQueue',
+ name: QueueConstants.PUBLISH_QUEUE_NAME,
defaultJobOptions: {
attempts: 1,
backoff: {
diff --git a/services/content-watcher/apps/worker/src/publisher/publishing.service.ts b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
index 88bd6f47..3e58c06b 100644
--- a/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
+++ b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
@@ -11,9 +11,10 @@ import { ConfigService } from '../../../api/src/config/config.service';
import { IPublisherJob } from '../interfaces/publisher-job.interface';
import { IPFSPublisher } from './ipfs.publisher';
import { CAPACITY_EPOCH_TIMEOUT_NAME, SECONDS_PER_BLOCK } from '../../../../libs/common/src/constants';
+import { QueueConstants } from '../../../../libs/common/src';
@Injectable()
-@Processor('publishQueue', {
+@Processor(QueueConstants.PUBLISH_QUEUE_NAME, {
concurrency: 2,
})
export class PublishingService extends WorkerHost implements OnApplicationBootstrap, OnModuleDestroy {
@@ -23,7 +24,7 @@ export class PublishingService extends WorkerHost implements OnApplicationBootst
constructor(
@InjectRedis() private cacheManager: Redis,
- @InjectQueue('publishQueue') private publishQueue: Queue,
+ @InjectQueue(QueueConstants.PUBLISH_QUEUE_NAME) private publishQueue: Queue,
private blockchainService: BlockchainService,
private configService: ConfigService,
private ipfsPublisher: IPFSPublisher,
diff --git a/services/content-watcher/libs/common/src/constants.ts b/services/content-watcher/libs/common/src/constants.ts
index 94798661..8ea7d791 100644
--- a/services/content-watcher/libs/common/src/constants.ts
+++ b/services/content-watcher/libs/common/src/constants.ts
@@ -1,34 +1,8 @@
/**
- * Regex for ISO 8601
- * - T separation
- * - Required Time
- * - Supports fractional seconds
- * - Z or hour minute offset
+ * Number of seconds to create a block in Frequency chain
*/
-export const ISO8601_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,})?(Z|[+-][01][0-9]:[0-5][0-9])?$/;
-/**
- * DSNP user URI based on DSNP Spec
- * example: dsnp://78187493520
- */
-export const DSNP_USER_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}$/i;
-/**
- * DSNP content URI based on DSNP Spec
- * example: dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef
- */
-export const DSNP_CONTENT_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}\/0x[0-9a-f]+$/i;
-/**
- * DSNP character ranges for valid emojis
- */
-export const DSNP_EMOJI_REGEX = /^[\u{2000}-\u{2BFF}\u{E000}-\u{FFFF}\u{1F000}-\u{FFFFF}]+$/u;
-/**
- * Activity Stream Duration based on https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
- */
-export const DURATION_REGEX = /^-?P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+(\.[0-9]+)?S)?)?)+$/;
-
+export const SECONDS_PER_BLOCK = 12;
/**
- * Dsnp attachments mime types
+ * Name of timeout event used for in memory scheduler
*/
-export const DSNP_VALID_MIME_TYPES =
- /(image\/jpeg|image\/png|image\/svg\+xml|image\/webp|image\/gif|video\/mpeg|video\/ogg|video\/webm|video\/H256|video\/mp4|audio\/mpeg|audio\/ogg|audio\/webm)$/;
-export const SECONDS_PER_BLOCK = 12;
export const CAPACITY_EPOCH_TIMEOUT_NAME = 'capacity-epoch-timeout';
diff --git a/services/content-watcher/libs/common/src/dtos/activity.dto.ts b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
index 34cd367f..2c079705 100644
--- a/services/content-watcher/libs/common/src/dtos/activity.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/activity.dto.ts
@@ -22,7 +22,7 @@ import {
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
-import { DSNP_USER_URI_REGEX, DURATION_REGEX, ISO8601_REGEX } from '../constants';
+import { DSNP_USER_URI_REGEX, DURATION_REGEX, ISO8601_REGEX } from './validation.dto';
// eslint-disable-next-line no-shadow
export enum UnitTypeDto {
diff --git a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
index 8466d931..857d463f 100644
--- a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
@@ -5,10 +5,10 @@
import { IsEnum, IsInt, IsNotEmpty, IsString, Matches, Max, MaxLength, Min, MinLength, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { NoteActivityDto, ProfileActivityDto } from './activity.dto';
-import { DSNP_CONTENT_URI_REGEX, DSNP_EMOJI_REGEX } from '../constants';
+import { DSNP_CONTENT_URI_REGEX, DSNP_EMOJI_REGEX } from './validation.dto';
// eslint-disable-next-line no-shadow
-export enum AnnouncementTypeDto {
+export enum UpdateAnnouncementTypeDto {
BROADCAST = 'broadcast',
REPLY = 'reply',
}
@@ -32,8 +32,8 @@ export class ReplyDto {
}
export class UpdateDto {
- @IsEnum(AnnouncementTypeDto)
- targetAnnouncementType: AnnouncementTypeDto;
+ @IsEnum(UpdateAnnouncementTypeDto)
+ targetAnnouncementType: UpdateAnnouncementTypeDto;
@IsNotEmpty()
@ValidateNested()
@@ -63,3 +63,5 @@ export class ProfileDto {
@Type(() => ProfileActivityDto)
profile: ProfileActivityDto;
}
+
+export type RequestTypeDto = BroadcastDto | ReplyDto | ReactionDto | UpdateDto | ProfileDto;
diff --git a/services/content-watcher/libs/common/src/dtos/common.dto.ts b/services/content-watcher/libs/common/src/dtos/common.dto.ts
index 6b325f1e..68040caf 100644
--- a/services/content-watcher/libs/common/src/dtos/common.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/common.dto.ts
@@ -29,3 +29,13 @@ export class FilesUploadDto {
@ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
files: any[];
}
+
+// eslint-disable-next-line no-shadow
+export enum AnnouncementTypeDto {
+ BROADCAST = 'broadcast',
+ REPLY = 'reply',
+ REACTION = 'reaction',
+ UPDATE = 'update',
+ TOMBSTONE = 'tombstone',
+ PROFILE = 'profile',
+}
diff --git a/services/content-watcher/libs/common/src/dtos/validation.dto.ts b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
new file mode 100644
index 00000000..b867b109
--- /dev/null
+++ b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
@@ -0,0 +1,32 @@
+/**
+ * Regex for ISO 8601
+ * - T separation
+ * - Required Time
+ * - Supports fractional seconds
+ * - Z or hour minute offset
+ * - example: 1970-01-01T00:00:00+00:00
+ */
+export const ISO8601_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,})?(Z|[+-][01][0-9]:[0-5][0-9])?$/;
+/**
+ * DSNP user URI based on DSNP Spec
+ * example: dsnp://78187493520
+ */
+export const DSNP_USER_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}$/i;
+/**
+ * DSNP content URI based on DSNP Spec
+ * example: dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+ */
+export const DSNP_CONTENT_URI_REGEX = /^dsnp:\/\/[1-9][0-9]{0,19}\/0x[0-9a-f]+$/i;
+/**
+ * DSNP character ranges for valid emojis
+ */
+export const DSNP_EMOJI_REGEX = /^[\u{2000}-\u{2BFF}\u{E000}-\u{FFFF}\u{1F000}-\u{FFFFF}]+$/u;
+/**
+ * Activity Stream Duration based on https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
+ */
+export const DURATION_REGEX = /^-?P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+(\.[0-9]+)?S)?)?)+$/;
+/**
+ * Dsnp attachments mime types
+ */
+export const DSNP_VALID_MIME_TYPES =
+ /(image\/jpeg|image\/png|image\/svg\+xml|image\/webp|image\/gif|video\/mpeg|video\/ogg|video\/webm|video\/H256|video\/mp4|audio\/mpeg|audio\/ogg|audio\/webm)$/;
diff --git a/services/content-watcher/libs/common/src/index.ts b/services/content-watcher/libs/common/src/index.ts
index 9e674f38..d12f6422 100644
--- a/services/content-watcher/libs/common/src/index.ts
+++ b/services/content-watcher/libs/common/src/index.ts
@@ -1,3 +1,6 @@
export * from './dtos/announcement.dto';
export * from './dtos/activity.dto';
export * from './dtos/common.dto';
+export * from './dtos/validation.dto';
+export * from './interfaces/request-job.interface';
+export * from './utils/queues';
diff --git a/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
new file mode 100644
index 00000000..0798cd4a
--- /dev/null
+++ b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
@@ -0,0 +1,10 @@
+import { RequestTypeDto } from '../dtos/announcement.dto';
+import { AnnouncementTypeDto } from '../dtos/common.dto';
+
+export interface IRequestJob {
+ id: string;
+ announcementType: AnnouncementTypeDto;
+ dsnpUserId: string;
+ targetContentHash?: string;
+ content?: RequestTypeDto;
+}
diff --git a/services/content-watcher/libs/common/src/utils/queues.ts b/services/content-watcher/libs/common/src/utils/queues.ts
new file mode 100644
index 00000000..e759e7a5
--- /dev/null
+++ b/services/content-watcher/libs/common/src/utils/queues.ts
@@ -0,0 +1,51 @@
+import { AnnouncementTypeDto } from '../dtos/common.dto';
+
+export namespace QueueConstants {
+ /**
+ * Name of the queue that has all incoming requests
+ */
+ export const REQUEST_QUEUE_NAME = 'requestQueue';
+ /**
+ * Name of the queue that has all individual announcements batched together
+ */
+ export const BATCH_QUEUE_NAME = 'batchQueue';
+ /**
+ * Name of the queue that has all items that needs to be published to Frequency chain
+ */
+ export const PUBLISH_QUEUE_NAME = 'publishQueue';
+ /**
+ * Name of the queue that has all the jobs and items that needs to run periodically or check their status
+ */
+ export const STATUS_QUEUE_NAME = 'statusQueue';
+ /**
+ * All of the announcement type queues
+ */
+ export const BROADCAST_QUEUE_NAME = 'broadcastQueue';
+ export const REPLY_QUEUE_NAME = 'replyQueue';
+ export const REACTION_QUEUE_NAME = 'reactionQueue';
+ export const UPDATE_QUEUE_NAME = 'updateQueue';
+ export const TOMBSTONE_QUEUE_NAME = 'tombstoneQueue';
+ export const PROFILE_QUEUE_NAME = 'profileQueue';
+ /**
+ * Map between announcement type and it's queueName
+ */
+ export const ANNOUNCEMENT_TO_QUEUE_NAME_MAP = new Map([
+ [AnnouncementTypeDto.BROADCAST, BROADCAST_QUEUE_NAME],
+ [AnnouncementTypeDto.REPLY, REPLY_QUEUE_NAME],
+ [AnnouncementTypeDto.REACTION, REACTION_QUEUE_NAME],
+ [AnnouncementTypeDto.UPDATE, UPDATE_QUEUE_NAME],
+ [AnnouncementTypeDto.TOMBSTONE, TOMBSTONE_QUEUE_NAME],
+ [AnnouncementTypeDto.PROFILE, PROFILE_QUEUE_NAME],
+ ]);
+ /**
+ * Map between queue name and it's announcement type
+ */
+ export const QUEUE_NAME_TO_ANNOUNCEMENT_MAP = new Map([
+ [BROADCAST_QUEUE_NAME, AnnouncementTypeDto.BROADCAST],
+ [REPLY_QUEUE_NAME, AnnouncementTypeDto.REPLY],
+ [REACTION_QUEUE_NAME, AnnouncementTypeDto.REACTION],
+ [UPDATE_QUEUE_NAME, AnnouncementTypeDto.UPDATE],
+ [TOMBSTONE_QUEUE_NAME, AnnouncementTypeDto.TOMBSTONE],
+ [PROFILE_QUEUE_NAME, AnnouncementTypeDto.PROFILE],
+ ]);
+}
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 1bc6bcab..128cb320 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -36,6 +36,7 @@
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
+ "crypto": "^1.0.1",
"ioredis": "^5.3.2",
"joi": "^17.9.1",
"rxjs": "^7.8.1",
@@ -4628,6 +4629,12 @@
"node": ">= 8"
}
},
+ "node_modules/crypto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
+ "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
+ "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
+ },
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"license": "MIT",
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 4de7f2fc..c2030f78 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -32,8 +32,8 @@
},
"homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
"dependencies": {
- "@jest/globals": "^29.5.0",
"@frequency-chain/api-augment": "1.7.0",
+ "@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
"@nestjs/axios": "^2.0.0",
"@nestjs/bullmq": "^10.0.0",
@@ -59,6 +59,7 @@
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
+ "crypto": "^1.0.1",
"ioredis": "^5.3.2",
"joi": "^17.9.1",
"rxjs": "^7.8.1",
@@ -68,9 +69,9 @@
"@polkadot/typegen": "10.9.1",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
+ "@types/node": "^20.3.1",
"@types/supertest": "^2.0.12",
"@types/time-constants": "^1.0.0",
- "@types/node": "^20.3.1",
"@typescript-eslint/parser": "^5.59.8",
"@typescript-eslint/typescript-estree": "5.59.8",
"dotenv": "^16.3.1",
@@ -86,8 +87,8 @@
"eslint-plugin-promise": "^6.1.1",
"license-report": "^6.4.0",
"supertest": "^6.3.3",
- "ts-loader": "^9.4.3",
"ts-jest": "^29.1.0",
+ "ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "^4.2.0",
From 453d856989bc25c27cb07b805c939334c4a4d22b Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 30 Aug 2023 13:52:51 -0500
Subject: [PATCH 009/137] add scaffolding for status monitoring (#26)
* add scaffodingly for status monitoring
* cleanup and move out some complex code
* cleanup
* cleanup
* do not clear publishQueue on complete
* error on bad txHash
* fix run
* register queues with respective modules
* cleanup
* hash fix
---
.../apps/worker/src/blockchain/extrinsic.ts | 59 ++++---------
.../interfaces/status-monitor.interface.ts | 7 ++
.../src/monitor/status.monitor.module.ts | 82 +++++++++++++++++++
.../src/monitor/status.monitor.service.ts | 60 ++++++++++++++
.../src/monitor/status.monitoring.spec.ts | 10 +++
.../worker/src/publisher/ipfs.publisher.ts | 81 ++++++------------
.../worker/src/publisher/publisher.module.ts | 31 +++++--
.../src/publisher/publishing.service.ts | 3 +-
.../apps/worker/src/worker.module.ts | 5 +-
.../libs/common/src/utils/queues.ts | 5 ++
10 files changed, 232 insertions(+), 111 deletions(-)
create mode 100644 services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
create mode 100644 services/content-watcher/apps/worker/src/monitor/status.monitor.module.ts
create mode 100644 services/content-watcher/apps/worker/src/monitor/status.monitor.service.ts
create mode 100644 services/content-watcher/apps/worker/src/monitor/status.monitoring.spec.ts
diff --git a/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts b/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
index a435e0ab..7472473c 100644
--- a/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
+++ b/services/content-watcher/apps/worker/src/blockchain/extrinsic.ts
@@ -26,12 +26,11 @@
import { ApiRx } from '@polkadot/api';
import { SubmittableExtrinsic, ApiTypes, AugmentedEvent } from '@polkadot/api/types';
-import { Call, Event } from '@polkadot/types/interfaces';
+import { Call, Event, EventRecord, Hash } from '@polkadot/types/interfaces';
import { IsEvent } from '@polkadot/types/metadata/decorate/types';
import { Codec, ISubmittableResult, AnyTuple } from '@polkadot/types/types';
import { filter, firstValueFrom, map, pipe, tap } from 'rxjs';
import { KeyringPair } from '@polkadot/keyring/types';
-import { ConfigService } from '../../../api/src/config/config.service';
import { EventError } from './event-error';
export type EventMap = { [key: string]: Event };
@@ -63,12 +62,19 @@ export class Extrinsic {
- return firstValueFrom(
- this.extrinsic.signAndSend(this.keys, { nonce }).pipe(
- filter(({ status }) => status.isInBlock || status.isFinalized),
- this.parseResult(this.event),
- ),
+ public signAndSend(nonce?: number): Promise<[Hash, EventMap]> {
+ return firstValueFrom(this.extrinsic.signAndSend(this.keys, { nonce }).pipe(filter(({ status }) => status.isInBlock || status.isFinalized))).then(
+ ({ status, events, txHash }) => {
+ if (status.isInBlock || status.isFinalized) {
+ const eventMap: EventMap = {};
+ events.forEach((record: EventRecord) => {
+ const { event } = record;
+ eventMap[eventKey(event)] = event;
+ });
+ return [txHash, eventMap];
+ }
+ throw new Error(`Transaction failed to finalize: ${txHash}`);
+ },
);
}
@@ -76,41 +82,4 @@ export class Extrinsic(targetEvent?: AugmentedEvent) {
- return pipe(
- tap((result: ISubmittableResult) => {
- if (result.dispatchError) {
- const err = new EventError(result.dispatchError);
- throw err;
- }
- }),
- map((result: ISubmittableResult) =>
- result.events.reduce((acc, { event }) => {
- acc[eventKey(event)] = event;
- if (targetEvent && targetEvent.is(event)) {
- acc.defaultEvent = event;
- }
- if (this.api.events.sudo.Sudid.is(event)) {
- const { sudoResult } = event.data;
- if (sudoResult.isErr) {
- const err = new EventError(sudoResult.asErr);
- throw err;
- }
- }
- return acc;
- }, {} as EventMap),
- ),
- map((em) => {
- const result: ParsedEventResult = [undefined, {}];
- if (targetEvent && targetEvent.is(em?.defaultEvent)) {
- result[0] = em.defaultEvent;
- }
- result[1] = em;
- return result;
- }),
- // tap((events) => console.log(events)),
- );
- }
}
diff --git a/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts b/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
new file mode 100644
index 00000000..e0f10ce0
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
@@ -0,0 +1,7 @@
+import { Hash } from "@polkadot/types/interfaces";
+
+export interface IStatusMonitorJob {
+ id: string;
+ txHash: Hash;
+ publisherJobId: string;
+}
diff --git a/services/content-watcher/apps/worker/src/monitor/status.monitor.module.ts b/services/content-watcher/apps/worker/src/monitor/status.monitor.module.ts
new file mode 100644
index 00000000..70a5452f
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/monitor/status.monitor.module.ts
@@ -0,0 +1,82 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { BullModule } from '@nestjs/bullmq';
+import { Module } from '@nestjs/common';
+import { EventEmitterModule } from '@nestjs/event-emitter';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { StatusMonitoringService } from './status.monitor.service';
+import { ConfigModule } from '../../../api/src/config/config.module';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { BlockchainModule } from '../blockchain/blockchain.module';
+import { QueueConstants } from '../../../../libs/common/src';
+
+@Module({
+ imports: [
+ ConfigModule,
+ BlockchainModule,
+ EventEmitterModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ BullModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => {
+ // Note: BullMQ doesn't honor a URL for the Redis connection, and
+ // JS URL doesn't parse 'redis://' as a valid protocol, so we fool
+ // it by changing the URL to use 'http://' in order to parse out
+ // the host, port, username, password, etc.
+ // We could pass REDIS_HOST, REDIS_PORT, etc, in the environment, but
+ // trying to keep the # of environment variables from proliferating
+ const url = new URL(configService.redisUrl.toString().replace(/^redis[s]*/, 'http'));
+ const { hostname, port, username, password, pathname } = url;
+ return {
+ connection: {
+ host: hostname || undefined,
+ port: port ? Number(port) : undefined,
+ username: username || undefined,
+ password: password || undefined,
+ db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
+ },
+ };
+ },
+ inject: [ConfigService],
+ }),
+ BullModule.registerQueue(
+ {
+ name: QueueConstants.TRANSACTION_RECEIPT_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: true,
+ removeOnFail: false,
+ },
+ },
+ {
+ name: QueueConstants.PUBLISH_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: true,
+ removeOnFail: false,
+ },
+ },
+ ),
+ ],
+ controllers: [],
+ providers: [StatusMonitoringService],
+ exports: [BullModule, StatusMonitoringService],
+})
+export class StatusMonitorModule {}
diff --git a/services/content-watcher/apps/worker/src/monitor/status.monitor.service.ts b/services/content-watcher/apps/worker/src/monitor/status.monitor.service.ts
new file mode 100644
index 00000000..c0347eb5
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/monitor/status.monitor.service.ts
@@ -0,0 +1,60 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Processor, WorkerHost, OnWorkerEvent, InjectQueue } from '@nestjs/bullmq';
+import { Injectable, Logger, OnApplicationBootstrap, OnModuleDestroy } from '@nestjs/common';
+import { Job, Queue } from 'bullmq';
+import Redis from 'ioredis';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { BlockchainService } from '../blockchain/blockchain.service';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IStatusMonitorJob } from '../interfaces/status-monitor.interface';
+import { QueueConstants } from '../../../../libs/common/src';
+
+@Injectable()
+@Processor(QueueConstants.TRANSACTION_RECEIPT_QUEUE_NAME, {
+ concurrency: 2,
+})
+export class StatusMonitoringService extends WorkerHost implements OnApplicationBootstrap, OnModuleDestroy {
+ private logger: Logger;
+
+ constructor(
+ @InjectRedis() private cacheManager: Redis,
+ @InjectQueue(QueueConstants.PUBLISH_QUEUE_NAME) private publishQueue: Queue,
+ private blockchainService: BlockchainService,
+ private configService: ConfigService,
+ private eventEmitter: EventEmitter2,
+ ) {
+ super();
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ public async onApplicationBootstrap() {
+ this.logger.debug('Starting publishing service');
+ }
+
+ public onModuleDestroy() {
+ try {
+ this.logger.debug('Shutting down publishing service');
+ } catch (e) {
+ // 💀 //
+ }
+ }
+
+ async process(job: Job): Promise {
+ this.logger.log(`Processing job ${job.id} of type ${job.name}`);
+ try {
+ this.logger.verbose(`Successfully completed job ${job.id}`);
+ return { success: true };
+ } catch (e) {
+ this.logger.error(`Job ${job.id} failed (attempts=${job.attemptsMade})`);
+ throw e;
+ } finally {
+ // do some stuff
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ onCompleted() {
+ // do some stuff
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/monitor/status.monitoring.spec.ts b/services/content-watcher/apps/worker/src/monitor/status.monitoring.spec.ts
new file mode 100644
index 00000000..25938c2d
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/monitor/status.monitoring.spec.ts
@@ -0,0 +1,10 @@
+// test file for ipfs publisher
+import { describe, it, beforeEach } from '@jest/globals';
+
+describe('Status Monitoring', () => {
+ beforeEach(async () => {});
+
+ describe('check status', () => {
+ it('should handle tx receipts', async () => {});
+ });
+});
diff --git a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
index 064c77fd..c00f46a5 100644
--- a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
+++ b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
@@ -3,16 +3,21 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import { KeyringPair } from '@polkadot/keyring/types';
import { ISubmittableResult } from '@polkadot/types/types';
import { SubmittableExtrinsic } from '@polkadot/api-base/types';
+import { InjectQueue } from '@nestjs/bullmq';
+import { Hash } from '@polkadot/types/interfaces';
import { BlockchainService } from '../blockchain/blockchain.service';
import { ConfigService } from '../../../api/src/config/config.service';
import { IPublisherJob } from '../interfaces/publisher-job.interface';
import { createKeys } from '../blockchain/create-keys';
+import { IStatusMonitorJob } from '../interfaces/status-monitor.interface';
+import { QueueConstants } from '../../../../libs/common/src';
@Injectable()
export class IPFSPublisher {
private logger: Logger;
constructor(
+ @InjectQueue(QueueConstants.TRANSACTION_RECEIPT_QUEUE_NAME) private txReceiptQueue,
private configService: ConfigService,
private blockchainService: BlockchainService,
private eventEmitter: EventEmitter2,
@@ -20,69 +25,28 @@ export class IPFSPublisher {
this.logger = new Logger(IPFSPublisher.name);
}
- public async publish(messages: IPublisherJob[]): Promise<{ [key: string]: bigint }> {
+ public async publish(message: IPublisherJob): Promise<{ [key: string]: bigint }> {
const providerKeys = createKeys(this.configService.getProviderAccountSeedPhrase());
- let batch: SubmittableExtrinsic<'rxjs', ISubmittableResult>[] = [];
- const batches: SubmittableExtrinsic<'rxjs', ISubmittableResult>[][] = [];
- const allowedBatchLen = await this.blockchainService.capacityBatchLimit();
- messages.forEach((message) => {
- batch.push(this.blockchainService.createExtrinsicCall({ pallet: 'messages', extrinsic: 'addIpfsMessage' }, message.schemaId, message.data.cid, message.data.payloadLength));
-
- if (batch.length === allowedBatchLen) {
- batches.push(batch);
- batch = [];
- }
- });
-
- if (batch.length > 0) {
- batches.push(batch);
- }
- return this.sendAndProcessChainEvents(providerKeys, batches);
+ const batch: SubmittableExtrinsic<'rxjs', ISubmittableResult>[] = [];
+ const tx = this.blockchainService.createExtrinsicCall({ pallet: 'messages', extrinsic: 'addIpfsMessage' }, message.schemaId, message.data.cid, message.data.payloadLength);
+ return this.processSingleBatch(message.id, providerKeys, tx);
}
- async sendAndProcessChainEvents(providerKeys: KeyringPair, batchesMap: SubmittableExtrinsic<'rxjs', ISubmittableResult>[][]): Promise<{ [key: string]: bigint }> {
- try {
- // iterate over batches and send them to the chain returning the capacity withdrawn
- const batchPromises: Promise<{ [key: string]: bigint }>[] = [];
-
- batchesMap.forEach(async (batch) => {
- batchPromises.push(this.processSingleBatch(providerKeys, batch));
- });
-
- const totalCapUsedPerEpoch = await Promise.all(batchPromises);
- const totalCapacityUsed = totalCapUsedPerEpoch.reduce(
- (acc, curr) => {
- const epoch = Object.keys(curr)[0];
- if (acc[epoch]) {
- acc[epoch] += curr[epoch];
- }
- acc[epoch] = curr[epoch];
- return acc;
- },
- {} as { [key: string]: bigint },
- );
-
- this.logger.debug(`Total capacity used: ${JSON.stringify(totalCapacityUsed)}`);
- return totalCapacityUsed;
- } catch (e) {
- this.logger.error(`Error processing batches: ${e}`);
- throw e;
- }
- }
-
- async processSingleBatch(providerKeys: KeyringPair, batch: SubmittableExtrinsic<'rxjs', ISubmittableResult>[]): Promise<{ [key: string]: bigint }> {
- this.logger.debug(`Submitting batch of size ${batch.length}`);
+ async processSingleBatch(jobId: string, providerKeys: KeyringPair, tx: SubmittableExtrinsic<'rxjs', ISubmittableResult>): Promise<{ [key: string]: bigint }> {
+ this.logger.debug(`Submitting tx of size ${tx.length}`);
try {
const currrentEpoch = await this.blockchainService.getCurrentCapacityEpoch();
- const [event, eventMap] = await this.blockchainService
- .createExtrinsic({ pallet: 'frequencyTxPayment', extrinsic: 'payWithCapacityBatchAll' }, { eventPallet: 'utility', event: 'BatchCompleted' }, providerKeys, batch)
+ const [txHash, eventMap] = await this.blockchainService
+ .createExtrinsic({ pallet: 'frequencyTxPayment', extrinsic: 'payWithCapacity' }, { eventPallet: 'messages', event: 'MessagesStored' }, providerKeys, [tx])
.signAndSend();
- if (!event || !this.blockchainService.api.events.utility.BatchCompleted.is(event)) {
- // if we dont get any events, covering any unexpected connection errors
- throw new Error(`No events were found for batch`);
+ if (!txHash) {
+ throw new Error('Tx hash is undefined');
}
+
const capacityWithDrawn = BigInt(eventMap['capacity.CapacityWithdrawn'].data[1].toString());
+
+ this.sendJobToTxReceiptQueue(jobId, txHash);
this.logger.debug(`Batch processed, capacity withdrawn: ${capacityWithDrawn}`);
return { [currrentEpoch.toString()]: capacityWithDrawn };
} catch (e) {
@@ -90,4 +54,13 @@ export class IPFSPublisher {
throw e;
}
}
+
+ async sendJobToTxReceiptQueue(jobId: any, txHash: Hash): Promise {
+ const job: IStatusMonitorJob = {
+ id: txHash.toString(),
+ txHash: txHash,
+ publisherJobId: jobId,
+ };
+ await this.txReceiptQueue.add(txHash.toString(), job, { removeOnComplete: true, removeOnFail: true });
+ }
}
diff --git a/services/content-watcher/apps/worker/src/publisher/publisher.module.ts b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
index 583db9a3..1a95ca3c 100644
--- a/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
+++ b/services/content-watcher/apps/worker/src/publisher/publisher.module.ts
@@ -51,17 +51,30 @@ import { QueueConstants } from '../../../../libs/common/src';
},
inject: [ConfigService],
}),
- BullModule.registerQueue({
- name: QueueConstants.PUBLISH_QUEUE_NAME,
- defaultJobOptions: {
- attempts: 1,
- backoff: {
- type: 'exponential',
+ BullModule.registerQueue(
+ {
+ name: QueueConstants.PUBLISH_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: false,
+ removeOnFail: false,
},
- removeOnComplete: true,
- removeOnFail: false,
},
- }),
+ {
+ name: QueueConstants.TRANSACTION_RECEIPT_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: false,
+ removeOnFail: false,
+ },
+ },
+ ),
],
controllers: [],
providers: [PublishingService, IPFSPublisher],
diff --git a/services/content-watcher/apps/worker/src/publisher/publishing.service.ts b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
index 3e58c06b..b84900d3 100644
--- a/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
+++ b/services/content-watcher/apps/worker/src/publisher/publishing.service.ts
@@ -50,8 +50,7 @@ export class PublishingService extends WorkerHost implements OnApplicationBootst
async process(job: Job): Promise {
this.logger.log(`Processing job ${job.id} of type ${job.name}`);
try {
- // TODO: this is only performing one message per batch, figure out how to batch multiple messages
- const totalCapacityUsed = await this.ipfsPublisher.publish([job.data]);
+ const totalCapacityUsed = await this.ipfsPublisher.publish(job.data);
await this.setEpochCapacity(totalCapacityUsed);
this.logger.verbose(`Successfully completed job ${job.id}`);
diff --git a/services/content-watcher/apps/worker/src/worker.module.ts b/services/content-watcher/apps/worker/src/worker.module.ts
index 010cd3c6..745e3d87 100644
--- a/services/content-watcher/apps/worker/src/worker.module.ts
+++ b/services/content-watcher/apps/worker/src/worker.module.ts
@@ -9,6 +9,8 @@ import { WorkerService } from './worker.service';
import { ConfigService } from '../../api/src/config/config.service';
import { BlockchainModule } from './blockchain/blockchain.module';
import { ConfigModule } from '../../api/src/config/config.module';
+import { StatusMonitorModule } from './monitor/status.monitor.module';
+import { StatusMonitoringService } from './monitor/status.monitor.service';
@Module({
imports: [
@@ -45,7 +47,8 @@ import { ConfigModule } from '../../api/src/config/config.module';
ScheduleModule.forRoot(),
PublisherModule,
BlockchainModule,
+ StatusMonitorModule,
],
- providers: [ConfigService, WorkerService, PublishingService],
+ providers: [ConfigService, WorkerService, PublishingService, StatusMonitoringService],
})
export class WorkerModule {}
diff --git a/services/content-watcher/libs/common/src/utils/queues.ts b/services/content-watcher/libs/common/src/utils/queues.ts
index e759e7a5..2db48f4a 100644
--- a/services/content-watcher/libs/common/src/utils/queues.ts
+++ b/services/content-watcher/libs/common/src/utils/queues.ts
@@ -17,6 +17,11 @@ export namespace QueueConstants {
* Name of the queue that has all the jobs and items that needs to run periodically or check their status
*/
export const STATUS_QUEUE_NAME = 'statusQueue';
+
+ /**
+ * Name of the queue that has all the transaction receipts
+ */
+ export const TRANSACTION_RECEIPT_QUEUE_NAME = 'transactionReceiptQueue';
/**
* All of the announcement type queues
*/
From 07a917dfa38b02b64591f2e598819974b877d0fd Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 30 Aug 2023 14:12:11 -0500
Subject: [PATCH 010/137] scaffolding for batch announcer (#19)
* scaffolding for batch announcer
* import parquet js from dsnp
* lint
* address feedback
* lint
* cleanup
---
.../batch_announcer/batch.announcer.module.ts | 81 +
.../batch.announcer.service.ts | 64 +
.../batch_announcer/ipfs.announcer.spec.ts | 13 +
.../src/batch_announcer/ipfs.announcer.ts | 22 +
.../batch-announcer.job.interface.ts | 4 +
.../interfaces/status-monitor.interface.ts | 2 +-
.../worker/src/publisher/ipfs.publisher.ts | 2 +-
.../apps/worker/src/worker.module.ts | 5 +-
services/content-watcher/package-lock.json | 1441 ++++++++++-------
services/content-watcher/package.json | 1 +
10 files changed, 1011 insertions(+), 624 deletions(-)
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
create mode 100644 services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
new file mode 100644
index 00000000..206e1284
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
@@ -0,0 +1,81 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { BullModule } from '@nestjs/bullmq';
+import { Module } from '@nestjs/common';
+import { EventEmitterModule } from '@nestjs/event-emitter';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { BatchAnnouncementService } from './batch.announcer.service';
+import { ConfigModule } from '../../../api/src/config/config.module';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IPFSAnnouncer } from './ipfs.announcer';
+import { QueueConstants } from '../../../../libs/common/src';
+
+@Module({
+ imports: [
+ ConfigModule,
+ EventEmitterModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ BullModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => {
+ // Note: BullMQ doesn't honor a URL for the Redis connection, and
+ // JS URL doesn't parse 'redis://' as a valid protocol, so we fool
+ // it by changing the URL to use 'http://' in order to parse out
+ // the host, port, username, password, etc.
+ // We could pass REDIS_HOST, REDIS_PORT, etc, in the environment, but
+ // trying to keep the # of environment variables from proliferating
+ const url = new URL(configService.redisUrl.toString().replace(/^redis[s]*/, 'http'));
+ const { hostname, port, username, password, pathname } = url;
+ return {
+ connection: {
+ host: hostname || undefined,
+ port: port ? Number(port) : undefined,
+ username: username || undefined,
+ password: password || undefined,
+ db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
+ },
+ };
+ },
+ inject: [ConfigService],
+ }),
+ BullModule.registerQueue(
+ {
+ name: QueueConstants.PUBLISH_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: true,
+ removeOnFail: false,
+ },
+ },
+ {
+ name: QueueConstants.BATCH_QUEUE_NAME,
+ defaultJobOptions: {
+ attempts: 1,
+ backoff: {
+ type: 'exponential',
+ },
+ removeOnComplete: true,
+ removeOnFail: false,
+ },
+ },
+ ),
+ ],
+ controllers: [],
+ providers: [BatchAnnouncementService, IPFSAnnouncer],
+ exports: [BullModule, BatchAnnouncementService, IPFSAnnouncer],
+})
+export class BatchAnnouncerModule {}
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
new file mode 100644
index 00000000..9a9ce51b
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
@@ -0,0 +1,64 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Processor, WorkerHost, OnWorkerEvent, InjectQueue } from '@nestjs/bullmq';
+import { Injectable, Logger, OnApplicationBootstrap, OnModuleDestroy } from '@nestjs/common';
+import { Job, Queue } from 'bullmq';
+import Redis from 'ioredis';
+import { SchedulerRegistry } from '@nestjs/schedule';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IPFSAnnouncer } from './ipfs.announcer';
+import { CAPACITY_EPOCH_TIMEOUT_NAME } from '../../../../libs/common/src/constants';
+import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
+import { QueueConstants } from '../../../../libs/common/src';
+
+@Injectable()
+@Processor(QueueConstants.BATCH_QUEUE_NAME, {
+ concurrency: 2,
+})
+export class BatchAnnouncementService extends WorkerHost implements OnApplicationBootstrap, OnModuleDestroy {
+ private logger: Logger;
+
+ private capacityExhausted = false;
+
+ constructor(
+ @InjectRedis() private cacheManager: Redis,
+ @InjectQueue(QueueConstants.PUBLISH_QUEUE_NAME) private publishQueue: Queue,
+ private configService: ConfigService,
+ private ipfsPublisher: IPFSAnnouncer,
+ private schedulerRegistry: SchedulerRegistry,
+ private eventEmitter: EventEmitter2,
+ ) {
+ super();
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ public async onApplicationBootstrap() {
+ this.logger.log('onApplicationBootstrap');
+ }
+
+ public onModuleDestroy() {
+ try {
+ this.schedulerRegistry.deleteTimeout(CAPACITY_EPOCH_TIMEOUT_NAME);
+ } catch (e) {
+ // 💀 //
+ }
+ }
+
+ async process(job: Job): Promise {
+ this.logger.log(`Processing job ${job.id} of type ${job.name}`);
+ try {
+ await this.ipfsPublisher.announce(job.data);
+ this.logger.log(`Completed job ${job.id} of type ${job.name}`);
+ return job.data;
+ } catch (e) {
+ this.logger.error(`Error processing job ${job.id} of type ${job.name}: ${e}`);
+ throw e;
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ onCompleted() {
+ // do some stuff
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
new file mode 100644
index 00000000..fafa3c61
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
@@ -0,0 +1,13 @@
+// test file for ipfs announcer
+import { describe, it, beforeEach } from '@jest/globals';
+import { IPFSAnnouncer } from './ipfs.announcer';
+
+describe('IPFSAnnouncer', () => {
+ let ipfsAnnouncer: IPFSAnnouncer;
+
+ beforeEach(async () => {});
+
+ describe('announce', () => {
+ it('should announce a batch on ipfs', async () => {});
+ });
+});
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
new file mode 100644
index 00000000..bc94d958
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
@@ -0,0 +1,22 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { EventEmitter2 } from '@nestjs/event-emitter';
+import { BlockchainService } from '../blockchain/blockchain.service';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
+
+@Injectable()
+export class IPFSAnnouncer {
+ private logger: Logger;
+
+ constructor(
+ private configService: ConfigService,
+ private blockchainService: BlockchainService,
+ private eventEmitter: EventEmitter2,
+ ) {
+ this.logger = new Logger(IPFSAnnouncer.name);
+ }
+
+ public async announce(batchJob: IBatchAnnouncerJobData): Promise {
+ this.logger.log(`Announcing batch ${batchJob.batchId} on IPFS`);
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts b/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
new file mode 100644
index 00000000..25d5bbf9
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
@@ -0,0 +1,4 @@
+export interface IBatchAnnouncerJobData {
+ batchId: string;
+ schemaId: number;
+}
diff --git a/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts b/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
index e0f10ce0..c896f558 100644
--- a/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
+++ b/services/content-watcher/apps/worker/src/interfaces/status-monitor.interface.ts
@@ -1,4 +1,4 @@
-import { Hash } from "@polkadot/types/interfaces";
+import { Hash } from '@polkadot/types/interfaces';
export interface IStatusMonitorJob {
id: string;
diff --git a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
index c00f46a5..31279c76 100644
--- a/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
+++ b/services/content-watcher/apps/worker/src/publisher/ipfs.publisher.ts
@@ -58,7 +58,7 @@ export class IPFSPublisher {
async sendJobToTxReceiptQueue(jobId: any, txHash: Hash): Promise {
const job: IStatusMonitorJob = {
id: txHash.toString(),
- txHash: txHash,
+ txHash,
publisherJobId: jobId,
};
await this.txReceiptQueue.add(txHash.toString(), job, { removeOnComplete: true, removeOnFail: true });
diff --git a/services/content-watcher/apps/worker/src/worker.module.ts b/services/content-watcher/apps/worker/src/worker.module.ts
index 745e3d87..ea631a37 100644
--- a/services/content-watcher/apps/worker/src/worker.module.ts
+++ b/services/content-watcher/apps/worker/src/worker.module.ts
@@ -9,6 +9,8 @@ import { WorkerService } from './worker.service';
import { ConfigService } from '../../api/src/config/config.service';
import { BlockchainModule } from './blockchain/blockchain.module';
import { ConfigModule } from '../../api/src/config/config.module';
+import { BatchAnnouncementService } from './batch_announcer/batch.announcer.service';
+import { BatchAnnouncerModule } from './batch_announcer/batch.announcer.module';
import { StatusMonitorModule } from './monitor/status.monitor.module';
import { StatusMonitoringService } from './monitor/status.monitor.service';
@@ -47,8 +49,9 @@ import { StatusMonitoringService } from './monitor/status.monitor.service';
ScheduleModule.forRoot(),
PublisherModule,
BlockchainModule,
+ BatchAnnouncerModule,
StatusMonitorModule,
],
- providers: [ConfigService, WorkerService, PublishingService, StatusMonitoringService],
+ providers: [BatchAnnouncementService, ConfigService, WorkerService, PublishingService, StatusMonitoringService],
})
export class WorkerModule {}
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 128cb320..d6f3ede8 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
+ "@dsnp/parquetjs": "^1.3.4",
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
@@ -674,12 +675,11 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.22.11",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz",
- "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==",
+ "version": "7.22.3",
+ "license": "MIT",
"peer": true,
"dependencies": {
- "regenerator-runtime": "^0.14.0"
+ "regenerator-runtime": "^0.13.11"
},
"engines": {
"node": ">=6.9.0"
@@ -737,9 +737,8 @@
},
"node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/@colors/colors": {
@@ -762,6 +761,29 @@
"node": ">=12"
}
},
+ "node_modules/@dsnp/parquetjs": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@dsnp/parquetjs/-/parquetjs-1.3.4.tgz",
+ "integrity": "sha512-DKRtMi+EZaoF/IUalz0UhSqRJ4P2/SCcL1aTwCJ5ZAgZGKFHKvOUYcCjM2XrMlsykfKcL3IMlJ4EZZONCGmRIQ==",
+ "dependencies": {
+ "@types/long": "^4.0.2",
+ "@types/node-int64": "^0.4.29",
+ "@types/thrift": "^0.10.11",
+ "browserify-zlib": "^0.2.0",
+ "bson": "4.6.3",
+ "cross-fetch": "^3.1.4",
+ "int53": "^0.2.4",
+ "long": "^4.0.0",
+ "snappyjs": "^0.6.1",
+ "thrift": "0.16.0",
+ "varint": "^6.0.0",
+ "wasm-brotli": "^2.0.2",
+ "xxhash-wasm": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=16.15.1"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"dev": true,
@@ -959,17 +981,16 @@
}
},
"node_modules/@jest/console": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz",
- "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^29.6.3",
- "jest-util": "^29.6.3",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
"slash": "^3.0.0"
},
"engines": {
@@ -977,38 +998,37 @@
}
},
"node_modules/@jest/core": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz",
- "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.6.4",
- "@jest/reporters": "^29.6.4",
- "@jest/test-result": "^29.6.4",
- "@jest/transform": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/console": "^29.5.0",
+ "@jest/reporters": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.9",
- "jest-changed-files": "^29.6.3",
- "jest-config": "^29.6.4",
- "jest-haste-map": "^29.6.4",
- "jest-message-util": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.6.4",
- "jest-resolve-dependencies": "^29.6.4",
- "jest-runner": "^29.6.4",
- "jest-runtime": "^29.6.4",
- "jest-snapshot": "^29.6.4",
- "jest-util": "^29.6.3",
- "jest-validate": "^29.6.3",
- "jest-watcher": "^29.6.4",
+ "jest-changed-files": "^29.5.0",
+ "jest-config": "^29.5.0",
+ "jest-haste-map": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-resolve-dependencies": "^29.5.0",
+ "jest-runner": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
+ "jest-watcher": "^29.5.0",
"micromatch": "^4.0.4",
- "pretty-format": "^29.6.3",
+ "pretty-format": "^29.5.0",
"slash": "^3.0.0",
"strip-ansi": "^6.0.0"
},
@@ -1025,85 +1045,79 @@
}
},
"node_modules/@jest/environment": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz",
- "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/fake-timers": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
- "jest-mock": "^29.6.3"
+ "jest-mock": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/expect": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz",
- "integrity": "sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "expect": "^29.6.4",
- "jest-snapshot": "^29.6.4"
+ "expect": "^29.5.0",
+ "jest-snapshot": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/expect-utils": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz",
- "integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "jest-get-type": "^29.6.3"
+ "jest-get-type": "^29.4.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/fake-timers": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz",
- "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@sinonjs/fake-timers": "^10.0.2",
"@types/node": "*",
- "jest-message-util": "^29.6.3",
- "jest-mock": "^29.6.3",
- "jest-util": "^29.6.3"
+ "jest-message-util": "^29.5.0",
+ "jest-mock": "^29.5.0",
+ "jest-util": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/globals": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz",
- "integrity": "sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/environment": "^29.6.4",
- "@jest/expect": "^29.6.4",
- "@jest/types": "^29.6.3",
- "jest-mock": "^29.6.3"
+ "@jest/environment": "^29.5.0",
+ "@jest/expect": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "jest-mock": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/reporters": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz",
- "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^29.6.4",
- "@jest/test-result": "^29.6.4",
- "@jest/transform": "^29.6.4",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
+ "@jest/console": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@jridgewell/trace-mapping": "^0.3.15",
"@types/node": "*",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
@@ -1111,13 +1125,13 @@
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
"istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.1.3",
- "jest-message-util": "^29.6.3",
- "jest-util": "^29.6.3",
- "jest-worker": "^29.6.4",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-worker": "^29.5.0",
"slash": "^3.0.0",
"string-length": "^4.0.1",
"strip-ansi": "^6.0.0",
@@ -1135,53 +1149,48 @@
}
}
},
- "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "node_modules/@jest/reporters/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
"dev": true,
+ "license": "MIT",
"peer": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz",
- "integrity": "sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==",
+ "node_modules/@jest/reporters/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.18",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=10"
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "version": "29.4.3",
+ "license": "MIT",
"dependencies": {
- "@sinclair/typebox": "^0.27.8"
+ "@sinclair/typebox": "^0.25.16"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/source-map": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
- "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
+ "version": "29.4.3",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.18",
+ "@jridgewell/trace-mapping": "^0.3.15",
"callsites": "^3.0.0",
"graceful-fs": "^4.2.9"
},
@@ -1189,26 +1198,39 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/@jest/source-map/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jest/source-map/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "version": "0.3.18",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/@jest/test-result": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz",
- "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/console": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
},
@@ -1217,15 +1239,14 @@
}
},
"node_modules/@jest/test-sequencer": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz",
- "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/test-result": "^29.6.4",
+ "@jest/test-result": "^29.5.0",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.6.4",
+ "jest-haste-map": "^29.5.0",
"slash": "^3.0.0"
},
"engines": {
@@ -1233,21 +1254,20 @@
}
},
"node_modules/@jest/transform": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz",
- "integrity": "sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
+ "@jest/types": "^29.5.0",
+ "@jridgewell/trace-mapping": "^0.3.15",
"babel-plugin-istanbul": "^6.1.1",
"chalk": "^4.0.0",
"convert-source-map": "^2.0.0",
"fast-json-stable-stringify": "^2.1.0",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.6.4",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.6.3",
+ "jest-haste-map": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-util": "^29.5.0",
"micromatch": "^4.0.4",
"pirates": "^4.0.4",
"slash": "^3.0.0",
@@ -1277,11 +1297,10 @@
}
},
"node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/schemas": "^29.6.3",
+ "@jest/schemas": "^29.4.3",
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
@@ -1791,8 +1810,7 @@
},
"node_modules/@nestjs/testing": {
"version": "9.4.3",
- "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.3.tgz",
- "integrity": "sha512-LDT8Ai2eKnTzvnPaJwWOK03qTaFap5uHHsJCv6dL0uKWk6hyF9jms8DjyVaGsaujCaXDG8izl1mDEER0OmxaZA==",
+ "license": "MIT",
"dependencies": {
"tslib": "2.5.3"
},
@@ -2443,6 +2461,65 @@
"node": ">=16"
}
},
+ "node_modules/@redis/bloom": {
+ "version": "1.2.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.5.8",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.1.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.4",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.1.3",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.0.4",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
"node_modules/@scure/base": {
"version": "1.1.1",
"funding": [
@@ -2469,9 +2546,8 @@
"license": "BSD-3-Clause"
},
"node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="
+ "version": "0.25.24",
+ "license": "MIT"
},
"node_modules/@sindresorhus/is": {
"version": "5.4.1",
@@ -2486,24 +2562,21 @@
},
"node_modules/@sinonjs/commons": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
- "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
+ "license": "BSD-3-Clause",
"dependencies": {
"type-detect": "4.0.8"
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "version": "10.1.0",
+ "license": "BSD-3-Clause",
"dependencies": {
"@sinonjs/commons": "^3.0.0"
}
},
"node_modules/@sqltools/formatter": {
"version": "1.2.5",
- "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz",
- "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==",
+ "license": "MIT",
"peer": true
},
"node_modules/@substrate/connect": {
@@ -2563,9 +2636,8 @@
},
"node_modules/@types/babel__core": {
"version": "7.20.1",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz",
- "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.20.7",
@@ -2577,9 +2649,8 @@
},
"node_modules/@types/babel__generator": {
"version": "7.6.4",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
- "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.0.0"
@@ -2587,9 +2658,8 @@
},
"node_modules/@types/babel__template": {
"version": "7.4.1",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
- "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.1.0",
@@ -2598,10 +2668,7 @@
},
"node_modules/@types/babel__traverse": {
"version": "7.20.1",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz",
- "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==",
- "dev": true,
- "peer": true,
+ "license": "MIT",
"dependencies": {
"@babel/types": "^7.20.7"
}
@@ -2683,8 +2750,7 @@
},
"node_modules/@types/graceful-fs": {
"version": "4.1.6",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
- "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
@@ -2735,6 +2801,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/long": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
+ },
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@@ -2753,11 +2824,28 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz",
"integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA=="
},
+ "node_modules/@types/node-int64": {
+ "version": "0.4.29",
+ "resolved": "https://registry.npmjs.org/@types/node-int64/-/node-int64-0.4.29.tgz",
+ "integrity": "sha512-rHXvenLTj/CcsmNAebaBOhxQ2MqEGl3yXZZcZ21XYR+gzGTTcpOy2N4IxpvTCz48loyQNatHvfn6GhIbbZ1R3Q==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
+ "node_modules/@types/prettier": {
+ "version": "2.7.3",
+ "license": "MIT"
+ },
+ "node_modules/@types/q": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
+ "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ=="
+ },
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@@ -2769,10 +2857,9 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
"node_modules/@types/semver": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz",
- "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==",
+ "version": "7.5.0",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/@types/send": {
@@ -2827,6 +2914,16 @@
"@types/superagent": "*"
}
},
+ "node_modules/@types/thrift": {
+ "version": "0.10.13",
+ "resolved": "https://registry.npmjs.org/@types/thrift/-/thrift-0.10.13.tgz",
+ "integrity": "sha512-zNapgGgZP2tOC8zhS10LPKdJxH+U0owZ1WWwDZASgyb5HZGj03P4Wm+Yd3YDXDQEjSRqO2XQznUH13tcG4dkIA==",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/node-int64": "*",
+ "@types/q": "*"
+ }
+ },
"node_modules/@types/time-constants": {
"version": "1.0.0",
"dev": true,
@@ -2853,18 +2950,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
- "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
- "@typescript-eslint/scope-manager": "5.62.0",
- "@typescript-eslint/type-utils": "5.62.0",
- "@typescript-eslint/utils": "5.62.0",
+ "@typescript-eslint/scope-manager": "5.59.11",
+ "@typescript-eslint/type-utils": "5.59.11",
+ "@typescript-eslint/utils": "5.59.11",
"debug": "^4.3.4",
- "graphemer": "^1.4.0",
+ "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
"semver": "^7.3.7",
@@ -2888,14 +2984,13 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
- "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0"
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2906,10 +3001,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
- "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2920,13 +3014,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
- "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/types": "5.59.11",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3006,14 +3099,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
- "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.62.0",
- "@typescript-eslint/utils": "5.62.0",
+ "@typescript-eslint/typescript-estree": "5.59.11",
+ "@typescript-eslint/utils": "5.59.11",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -3034,10 +3126,9 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
- "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3048,14 +3139,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
- "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+ "version": "5.59.11",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0",
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -3076,13 +3166,12 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
- "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/types": "5.59.11",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3160,18 +3249,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
- "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.62.0",
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/typescript-estree": "5.62.0",
+ "@typescript-eslint/scope-manager": "5.59.11",
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/typescript-estree": "5.59.11",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@@ -3187,14 +3275,13 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
- "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0"
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3205,10 +3292,9 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
- "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3219,14 +3305,13 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
- "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+ "version": "5.59.11",
"dev": true,
+ "license": "BSD-2-Clause",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0",
+ "@typescript-eslint/types": "5.59.11",
+ "@typescript-eslint/visitor-keys": "5.59.11",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -3247,13 +3332,12 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
- "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+ "version": "5.59.11",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/types": "5.59.11",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3577,8 +3661,7 @@
},
"node_modules/any-promise": {
"version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "license": "MIT",
"peer": true
},
"node_modules/anymatch": {
@@ -3594,8 +3677,7 @@
},
"node_modules/app-root-path": {
"version": "3.1.0",
- "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
- "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">= 6.0.0"
@@ -3701,6 +3783,17 @@
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true
},
+ "node_modules/async": {
+ "version": "3.2.3",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"license": "MIT"
@@ -3726,16 +3819,15 @@
}
},
"node_modules/babel-jest": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz",
- "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/transform": "^29.6.4",
+ "@jest/transform": "^29.5.0",
"@types/babel__core": "^7.1.14",
"babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^29.6.3",
+ "babel-preset-jest": "^29.5.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"slash": "^3.0.0"
@@ -3762,10 +3854,9 @@
}
},
"node_modules/babel-plugin-jest-hoist": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/template": "^7.3.3",
@@ -3799,13 +3890,12 @@
}
},
"node_modules/babel-preset-jest": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "babel-plugin-jest-hoist": "^29.6.3",
+ "babel-plugin-jest-hoist": "^29.5.0",
"babel-preset-current-node-syntax": "^1.0.0"
},
"engines": {
@@ -3964,6 +4054,24 @@
"node": ">=8"
}
},
+ "node_modules/browser-or-node": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz",
+ "integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg=="
+ },
+ "node_modules/browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dependencies": {
+ "pako": "~1.0.5"
+ }
+ },
+ "node_modules/browserify-zlib/node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ },
"node_modules/browserslist": {
"version": "4.21.8",
"funding": [
@@ -4007,16 +4115,47 @@
},
"node_modules/bser": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "license": "Apache-2.0",
"dependencies": {
"node-int64": "^0.4.0"
}
},
+ "node_modules/bson": {
+ "version": "4.6.3",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.3.tgz",
+ "integrity": "sha512-rAqP5hcUVJhXP2MCSNVsf0oM2OGU1So6A9pVRDYayvJ5+hygXHQApf87wd5NlhPM1J9RJnbqxIG/f8QTzRoQ4A==",
+ "dependencies": {
+ "buffer": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/bson/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"node_modules/buffer": {
"version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
@@ -4031,6 +4170,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"peer": true,
"dependencies": {
"base64-js": "^1.3.1",
@@ -4127,6 +4267,26 @@
"node": ">= 0.8"
}
},
+ "node_modules/cache-manager": {
+ "version": "4.1.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "async": "3.2.3",
+ "lodash.clonedeep": "^4.5.0",
+ "lru-cache": "^7.10.1"
+ }
+ },
+ "node_modules/cache-manager/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "license": "ISC",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/cacheable-lookup": {
"version": "7.0.0",
"dev": true,
@@ -4211,9 +4371,8 @@
},
"node_modules/char-regex": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
- "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -4282,9 +4441,8 @@
},
"node_modules/cjs-module-lexer": {
"version": "1.2.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
- "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/class-transformer": {
@@ -4313,8 +4471,7 @@
},
"node_modules/cli-highlight": {
"version": "2.1.11",
- "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz",
- "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==",
+ "license": "ISC",
"peer": true,
"dependencies": {
"chalk": "^4.0.0",
@@ -4334,8 +4491,7 @@
},
"node_modules/cli-highlight/node_modules/cliui": {
"version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "license": "ISC",
"peer": true,
"dependencies": {
"string-width": "^4.2.0",
@@ -4345,8 +4501,7 @@
},
"node_modules/cli-highlight/node_modules/yargs": {
"version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"cliui": "^7.0.2",
@@ -4363,8 +4518,7 @@
},
"node_modules/cli-highlight/node_modules/yargs-parser": {
"version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "license": "ISC",
"peer": true,
"engines": {
"node": ">=10"
@@ -4432,9 +4586,8 @@
},
"node_modules/co": {
"version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"iojs": ">= 1.0.0",
@@ -4442,10 +4595,9 @@
}
},
"node_modules/collect-v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
- "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
+ "version": "1.0.1",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/color-convert": {
@@ -4617,6 +4769,33 @@
"node": ">=12.0.0"
}
},
+ "node_modules/cross-fetch": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
+ "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
+ "dependencies": {
+ "node-fetch": "^2.6.12"
+ }
+ },
+ "node_modules/cross-fetch/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"license": "MIT",
@@ -4644,8 +4823,7 @@
},
"node_modules/date-fns": {
"version": "2.30.0",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
- "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.21.0"
@@ -4699,19 +4877,10 @@
}
},
"node_modules/dedent": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
- "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==",
+ "version": "0.7.0",
"dev": true,
- "peer": true,
- "peerDependencies": {
- "babel-plugin-macros": "^3.1.0"
- },
- "peerDependenciesMeta": {
- "babel-plugin-macros": {
- "optional": true
- }
- }
+ "license": "MIT",
+ "peer": true
},
"node_modules/deep-extend": {
"version": "0.6.0",
@@ -4841,9 +5010,8 @@
},
"node_modules/detect-newline": {
"version": "3.1.0",
- "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
- "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -4868,9 +5036,8 @@
}
},
"node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "version": "29.4.3",
+ "license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
@@ -4932,9 +5099,8 @@
},
"node_modules/emittery": {
"version": "0.13.1",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
- "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
@@ -5691,8 +5857,6 @@
},
"node_modules/exit": {
"version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
"dev": true,
"peer": true,
"engines": {
@@ -5700,15 +5864,14 @@
}
},
"node_modules/expect": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz",
- "integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/expect-utils": "^29.6.4",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.6.4",
- "jest-message-util": "^29.6.3",
- "jest-util": "^29.6.3"
+ "@jest/expect-utils": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -5875,8 +6038,7 @@
},
"node_modules/fb-watchman": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "license": "Apache-2.0",
"dependencies": {
"bser": "2.1.1"
}
@@ -6138,19 +6300,6 @@
"version": "1.0.0",
"license": "ISC"
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/function-bind": {
"version": "1.1.1",
"license": "MIT"
@@ -6180,6 +6329,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/generic-pool": {
+ "version": "3.9.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"license": "MIT",
@@ -6379,6 +6537,12 @@
"version": "4.2.11",
"license": "ISC"
},
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/graphemer": {
"version": "1.4.0",
"dev": true,
@@ -6493,8 +6657,7 @@
},
"node_modules/highlight.js": {
"version": "10.7.3",
- "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
- "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": "*"
@@ -6502,9 +6665,8 @@
},
"node_modules/html-escaper": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/http-cache-semantics": {
@@ -6598,9 +6760,8 @@
},
"node_modules/import-local": {
"version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"pkg-dir": "^4.2.0",
@@ -6678,6 +6839,11 @@
"node": ">=8"
}
},
+ "node_modules/int53": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/int53/-/int53-0.2.4.tgz",
+ "integrity": "sha512-a5jlKftS7HUOhkUyYD7j2sJ/ZnvWiNlZS1ldR+g1ifQ+/UuZXIE+YTc/lK1qGj/GwAU5F8Z0e1eVq2t1J5Ob2g=="
+ },
"node_modules/internal-slot": {
"version": "1.0.5",
"dev": true,
@@ -6846,9 +7012,8 @@
},
"node_modules/is-generator-fn": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7067,6 +7232,14 @@
"version": "2.0.0",
"license": "ISC"
},
+ "node_modules/isomorphic-ws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
+ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
+ "peerDependencies": {
+ "ws": "*"
+ }
+ },
"node_modules/istanbul-lib-coverage": {
"version": "3.2.0",
"license": "BSD-3-Clause",
@@ -7096,25 +7269,23 @@
}
},
"node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "version": "3.0.0",
"dev": true,
+ "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
+ "make-dir": "^3.0.0",
"supports-color": "^7.1.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=8"
}
},
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
"dev": true,
+ "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"debug": "^4.1.1",
@@ -7126,10 +7297,9 @@
}
},
"node_modules/istanbul-reports": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
- "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
+ "version": "3.1.5",
"dev": true,
+ "license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"html-escaper": "^2.0.0",
@@ -7147,16 +7317,15 @@
}
},
"node_modules/jest": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz",
- "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/core": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/core": "^29.5.0",
+ "@jest/types": "^29.5.0",
"import-local": "^3.0.2",
- "jest-cli": "^29.6.4"
+ "jest-cli": "^29.5.0"
},
"bin": {
"jest": "bin/jest.js"
@@ -7174,14 +7343,12 @@
}
},
"node_modules/jest-changed-files": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz",
- "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"execa": "^5.0.0",
- "jest-util": "^29.6.3",
"p-limit": "^3.1.0"
},
"engines": {
@@ -7190,9 +7357,8 @@
},
"node_modules/jest-changed-files/node_modules/execa": {
"version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -7214,9 +7380,8 @@
},
"node_modules/jest-changed-files/node_modules/human-signals": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
+ "license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=10.17.0"
@@ -7224,9 +7389,8 @@
},
"node_modules/jest-changed-files/node_modules/is-stream": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -7237,9 +7401,8 @@
},
"node_modules/jest-changed-files/node_modules/mimic-fn": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7247,9 +7410,8 @@
},
"node_modules/jest-changed-files/node_modules/npm-run-path": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"path-key": "^3.0.0"
@@ -7260,9 +7422,8 @@
},
"node_modules/jest-changed-files/node_modules/onetime": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"mimic-fn": "^2.1.0"
@@ -7276,38 +7437,36 @@
},
"node_modules/jest-changed-files/node_modules/strip-final-newline": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
}
},
"node_modules/jest-circus": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz",
- "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.6.4",
- "@jest/expect": "^29.6.4",
- "@jest/test-result": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/environment": "^29.5.0",
+ "@jest/expect": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "dedent": "^1.0.0",
+ "dedent": "^0.7.0",
"is-generator-fn": "^2.0.0",
- "jest-each": "^29.6.3",
- "jest-matcher-utils": "^29.6.4",
- "jest-message-util": "^29.6.3",
- "jest-runtime": "^29.6.4",
- "jest-snapshot": "^29.6.4",
- "jest-util": "^29.6.3",
+ "jest-each": "^29.5.0",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
"p-limit": "^3.1.0",
- "pretty-format": "^29.6.3",
+ "pretty-format": "^29.5.0",
"pure-rand": "^6.0.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
@@ -7317,22 +7476,21 @@
}
},
"node_modules/jest-cli": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz",
- "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/core": "^29.6.4",
- "@jest/test-result": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/core": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.9",
"import-local": "^3.0.2",
- "jest-config": "^29.6.4",
- "jest-util": "^29.6.3",
- "jest-validate": "^29.6.3",
+ "jest-config": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
"prompts": "^2.0.1",
"yargs": "^17.3.1"
},
@@ -7352,32 +7510,31 @@
}
},
"node_modules/jest-config": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz",
- "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^29.6.4",
- "@jest/types": "^29.6.3",
- "babel-jest": "^29.6.4",
+ "@jest/test-sequencer": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "babel-jest": "^29.5.0",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
- "jest-circus": "^29.6.4",
- "jest-environment-node": "^29.6.4",
- "jest-get-type": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.6.4",
- "jest-runner": "^29.6.4",
- "jest-util": "^29.6.3",
- "jest-validate": "^29.6.3",
+ "jest-circus": "^29.5.0",
+ "jest-environment-node": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-runner": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
"micromatch": "^4.0.4",
"parse-json": "^5.2.0",
- "pretty-format": "^29.6.3",
+ "pretty-format": "^29.5.0",
"slash": "^3.0.0",
"strip-json-comments": "^3.1.1"
},
@@ -7398,24 +7555,22 @@
}
},
"node_modules/jest-diff": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz",
- "integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.6.3"
+ "diff-sequences": "^29.4.3",
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-docblock": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz",
- "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==",
+ "version": "29.4.3",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"detect-newline": "^3.0.0"
@@ -7425,62 +7580,58 @@
}
},
"node_modules/jest-each": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz",
- "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "jest-util": "^29.6.3",
- "pretty-format": "^29.6.3"
+ "jest-get-type": "^29.4.3",
+ "jest-util": "^29.5.0",
+ "pretty-format": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-environment-node": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz",
- "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.6.4",
- "@jest/fake-timers": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/environment": "^29.5.0",
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
- "jest-mock": "^29.6.3",
- "jest-util": "^29.6.3"
+ "jest-mock": "^29.5.0",
+ "jest-util": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-get-type": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
+ "version": "29.4.3",
+ "license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-haste-map": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz",
- "integrity": "sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@types/graceful-fs": "^4.1.3",
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"graceful-fs": "^4.2.9",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.6.3",
- "jest-worker": "^29.6.4",
+ "jest-regex-util": "^29.4.3",
+ "jest-util": "^29.5.0",
+ "jest-worker": "^29.5.0",
"micromatch": "^4.0.4",
"walker": "^1.0.8"
},
@@ -7492,45 +7643,42 @@
}
},
"node_modules/jest-leak-detector": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz",
- "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.6.3"
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-matcher-utils": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz",
- "integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
- "jest-diff": "^29.6.4",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.6.3"
+ "jest-diff": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "pretty-format": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-message-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz",
- "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"micromatch": "^4.0.4",
- "pretty-format": "^29.6.3",
+ "pretty-format": "^29.5.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
},
@@ -7539,13 +7687,12 @@
}
},
"node_modules/jest-mock": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz",
- "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
- "jest-util": "^29.6.3"
+ "jest-util": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7553,9 +7700,8 @@
},
"node_modules/jest-pnp-resolver": {
"version": "1.2.3",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
- "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7570,26 +7716,24 @@
}
},
"node_modules/jest-regex-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
- "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
+ "version": "29.4.3",
+ "license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-resolve": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz",
- "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.6.4",
+ "jest-haste-map": "^29.5.0",
"jest-pnp-resolver": "^1.2.2",
- "jest-util": "^29.6.3",
- "jest-validate": "^29.6.3",
+ "jest-util": "^29.5.0",
+ "jest-validate": "^29.5.0",
"resolve": "^1.20.0",
"resolve.exports": "^2.0.0",
"slash": "^3.0.0"
@@ -7599,45 +7743,43 @@
}
},
"node_modules/jest-resolve-dependencies": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz",
- "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "jest-regex-util": "^29.6.3",
- "jest-snapshot": "^29.6.4"
+ "jest-regex-util": "^29.4.3",
+ "jest-snapshot": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-runner": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz",
- "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/console": "^29.6.4",
- "@jest/environment": "^29.6.4",
- "@jest/test-result": "^29.6.4",
- "@jest/transform": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/console": "^29.5.0",
+ "@jest/environment": "^29.5.0",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"chalk": "^4.0.0",
"emittery": "^0.13.1",
"graceful-fs": "^4.2.9",
- "jest-docblock": "^29.6.3",
- "jest-environment-node": "^29.6.4",
- "jest-haste-map": "^29.6.4",
- "jest-leak-detector": "^29.6.3",
- "jest-message-util": "^29.6.3",
- "jest-resolve": "^29.6.4",
- "jest-runtime": "^29.6.4",
- "jest-util": "^29.6.3",
- "jest-watcher": "^29.6.4",
- "jest-worker": "^29.6.4",
+ "jest-docblock": "^29.4.3",
+ "jest-environment-node": "^29.5.0",
+ "jest-haste-map": "^29.5.0",
+ "jest-leak-detector": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-resolve": "^29.5.0",
+ "jest-runtime": "^29.5.0",
+ "jest-util": "^29.5.0",
+ "jest-watcher": "^29.5.0",
+ "jest-worker": "^29.5.0",
"p-limit": "^3.1.0",
"source-map-support": "0.5.13"
},
@@ -7647,9 +7789,8 @@
},
"node_modules/jest-runner/node_modules/source-map-support": {
"version": "0.5.13",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
- "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
@@ -7657,32 +7798,31 @@
}
},
"node_modules/jest-runtime": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz",
- "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/environment": "^29.6.4",
- "@jest/fake-timers": "^29.6.4",
- "@jest/globals": "^29.6.4",
- "@jest/source-map": "^29.6.3",
- "@jest/test-result": "^29.6.4",
- "@jest/transform": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/environment": "^29.5.0",
+ "@jest/fake-timers": "^29.5.0",
+ "@jest/globals": "^29.5.0",
+ "@jest/source-map": "^29.4.3",
+ "@jest/test-result": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"chalk": "^4.0.0",
"cjs-module-lexer": "^1.0.0",
"collect-v8-coverage": "^1.0.0",
"glob": "^7.1.3",
"graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.6.4",
- "jest-message-util": "^29.6.3",
- "jest-mock": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.6.4",
- "jest-snapshot": "^29.6.4",
- "jest-util": "^29.6.3",
+ "jest-haste-map": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-mock": "^29.5.0",
+ "jest-regex-util": "^29.4.3",
+ "jest-resolve": "^29.5.0",
+ "jest-snapshot": "^29.5.0",
+ "jest-util": "^29.5.0",
"slash": "^3.0.0",
"strip-bom": "^4.0.0"
},
@@ -7692,50 +7832,50 @@
},
"node_modules/jest-runtime/node_modules/strip-bom": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
},
"node_modules/jest-snapshot": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz",
- "integrity": "sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
"@babel/generator": "^7.7.2",
"@babel/plugin-syntax-jsx": "^7.7.2",
"@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
"@babel/types": "^7.3.3",
- "@jest/expect-utils": "^29.6.4",
- "@jest/transform": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/expect-utils": "^29.5.0",
+ "@jest/transform": "^29.5.0",
+ "@jest/types": "^29.5.0",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
"babel-preset-current-node-syntax": "^1.0.0",
"chalk": "^4.0.0",
- "expect": "^29.6.4",
+ "expect": "^29.5.0",
"graceful-fs": "^4.2.9",
- "jest-diff": "^29.6.4",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.6.4",
- "jest-message-util": "^29.6.3",
- "jest-util": "^29.6.3",
+ "jest-diff": "^29.5.0",
+ "jest-get-type": "^29.4.3",
+ "jest-matcher-utils": "^29.5.0",
+ "jest-message-util": "^29.5.0",
+ "jest-util": "^29.5.0",
"natural-compare": "^1.4.0",
- "pretty-format": "^29.6.3",
- "semver": "^7.5.3"
+ "pretty-format": "^29.5.0",
+ "semver": "^7.3.5"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz",
- "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
@@ -7747,18 +7887,17 @@
}
},
"node_modules/jest-validate": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz",
- "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "^29.5.0",
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
+ "jest-get-type": "^29.4.3",
"leven": "^3.1.0",
- "pretty-format": "^29.6.3"
+ "pretty-format": "^29.5.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -7766,9 +7905,8 @@
},
"node_modules/jest-validate/node_modules/camelcase": {
"version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -7778,19 +7916,18 @@
}
},
"node_modules/jest-watcher": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz",
- "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==",
+ "version": "29.5.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jest/test-result": "^29.6.4",
- "@jest/types": "^29.6.3",
+ "@jest/test-result": "^29.5.0",
+ "@jest/types": "^29.5.0",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"emittery": "^0.13.1",
- "jest-util": "^29.6.3",
+ "jest-util": "^29.5.0",
"string-length": "^4.0.1"
},
"engines": {
@@ -7798,12 +7935,11 @@
}
},
"node_modules/jest-worker": {
- "version": "29.6.4",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz",
- "integrity": "sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
- "jest-util": "^29.6.3",
+ "jest-util": "^29.5.0",
"merge-stream": "^2.0.0",
"supports-color": "^8.0.0"
},
@@ -7813,8 +7949,7 @@
},
"node_modules/jest-worker/node_modules/supports-color": {
"version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -7918,9 +8053,8 @@
},
"node_modules/kleur": {
"version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -7928,9 +8062,8 @@
},
"node_modules/leven": {
"version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
@@ -8004,6 +8137,12 @@
"version": "4.17.21",
"license": "MIT"
},
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
"node_modules/lodash.defaults": {
"version": "4.2.0",
"license": "MIT"
@@ -8037,6 +8176,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
"node_modules/lower-case": {
"version": "2.0.2",
"dev": true,
@@ -8096,21 +8240,29 @@
}
},
"node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "version": "3.1.0",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "semver": "^7.5.3"
+ "semver": "^6.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/make-error": {
"version": "1.3.6",
"devOptional": true,
@@ -8118,8 +8270,7 @@
},
"node_modules/makeerror": {
"version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "license": "BSD-3-Clause",
"dependencies": {
"tmpl": "1.0.5"
}
@@ -8321,8 +8472,7 @@
},
"node_modules/mz": {
"version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"any-promise": "^1.0.0",
@@ -8336,9 +8486,8 @@
},
"node_modules/natural-compare-lite": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
- "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/negotiator": {
@@ -8432,8 +8581,7 @@
},
"node_modules/node-int64": {
"version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="
+ "license": "MIT"
},
"node_modules/node-releases": {
"version": "2.0.12",
@@ -8735,14 +8883,12 @@
},
"node_modules/parse5": {
"version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
- "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "license": "MIT",
"peer": true
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
- "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"parse5": "^6.0.1"
@@ -8750,8 +8896,7 @@
},
"node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
"version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
- "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "license": "MIT",
"peer": true
},
"node_modules/parseurl": {
@@ -8851,9 +8996,8 @@
},
"node_modules/pkg-dir": {
"version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"find-up": "^4.0.0"
@@ -8864,9 +9008,8 @@
},
"node_modules/pkg-dir/node_modules/find-up": {
"version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"locate-path": "^5.0.0",
@@ -8878,9 +9021,8 @@
},
"node_modules/pkg-dir/node_modules/locate-path": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"p-locate": "^4.1.0"
@@ -8891,9 +9033,8 @@
},
"node_modules/pkg-dir/node_modules/p-limit": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"p-try": "^2.0.0"
@@ -8907,9 +9048,8 @@
},
"node_modules/pkg-dir/node_modules/p-locate": {
"version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"p-limit": "^2.2.0"
@@ -8935,9 +9075,9 @@
}
},
"node_modules/prettier": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz",
- "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
+ "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
"dev": true,
"peer": true,
"bin": {
@@ -8962,11 +9102,10 @@
}
},
"node_modules/pretty-format": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz",
- "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==",
+ "version": "29.5.0",
+ "license": "MIT",
"dependencies": {
- "@jest/schemas": "^29.6.3",
+ "@jest/schemas": "^29.4.3",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
},
@@ -8990,9 +9129,8 @@
},
"node_modules/prompts": {
"version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"kleur": "^3.0.3",
@@ -9042,8 +9180,6 @@
},
"node_modules/pure-rand": {
"version": "6.0.2",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz",
- "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==",
"dev": true,
"funding": [
{
@@ -9055,8 +9191,18 @@
"url": "https://opencollective.com/fast-check"
}
],
+ "license": "MIT",
"peer": true
},
+ "node_modules/q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ }
+ },
"node_modules/qs": {
"version": "6.11.0",
"license": "BSD-3-Clause",
@@ -9192,6 +9338,23 @@
"node": ">= 0.10"
}
},
+ "node_modules/redis": {
+ "version": "4.6.7",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "workspaces": [
+ "./packages/*"
+ ],
+ "dependencies": {
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.5.8",
+ "@redis/graph": "1.1.0",
+ "@redis/json": "1.0.4",
+ "@redis/search": "1.1.3",
+ "@redis/time-series": "1.0.4"
+ }
+ },
"node_modules/redis-errors": {
"version": "1.2.0",
"license": "MIT",
@@ -9211,14 +9374,12 @@
},
"node_modules/reflect-metadata": {
"version": "0.1.13",
- "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+ "license": "Apache-2.0",
"peer": true
},
"node_modules/regenerator-runtime": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
+ "version": "0.13.11",
+ "license": "MIT",
"peer": true
},
"node_modules/regexp.prototype.flags": {
@@ -9293,9 +9454,8 @@
},
"node_modules/resolve-cwd": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
- "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"resolve-from": "^5.0.0"
@@ -9306,9 +9466,8 @@
},
"node_modules/resolve-cwd/node_modules/resolve-from": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
@@ -9331,9 +9490,8 @@
},
"node_modules/resolve.exports": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
- "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
"dev": true,
+ "license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
@@ -9597,9 +9755,8 @@
}
},
"node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.5.3",
+ "license": "ISC",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -9684,8 +9841,7 @@
},
"node_modules/sha.js": {
"version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "license": "(MIT AND BSD-3-Clause)",
"peer": true,
"dependencies": {
"inherits": "^2.0.1",
@@ -9746,9 +9902,8 @@
},
"node_modules/sisteransi": {
"version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/slash": {
@@ -9767,6 +9922,11 @@
"ws": "^8.8.1"
}
},
+ "node_modules/snappyjs": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/snappyjs/-/snappyjs-0.6.1.tgz",
+ "integrity": "sha512-YIK6I2lsH072UE0aOFxxY1dPDCS43I5ktqHpeAsuLNYWkE5pGxRGWfDM4/vSUfNzXjC1Ivzt3qx31PCLmc9yqg=="
+ },
"node_modules/source-map": {
"version": "0.6.1",
"license": "BSD-3-Clause",
@@ -9845,9 +10005,8 @@
},
"node_modules/string-length": {
"version": "4.0.2",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
- "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
"char-regex": "^1.0.2",
@@ -10173,8 +10332,7 @@
},
"node_modules/thenify": {
"version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"any-promise": "^1.0.0"
@@ -10182,8 +10340,7 @@
},
"node_modules/thenify-all": {
"version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"thenify": ">= 3.1.0 < 4"
@@ -10192,6 +10349,29 @@
"node": ">=0.8"
}
},
+ "node_modules/thrift": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/thrift/-/thrift-0.16.0.tgz",
+ "integrity": "sha512-W8DpGyTPlIaK3f+e1XOCLxefaUWXtrOXAaVIDbfYhmVyriYeAKgsBVFNJUV1F9SQ2SPt2sG44AZQxSGwGj/3VA==",
+ "dependencies": {
+ "browser-or-node": "^1.2.1",
+ "isomorphic-ws": "^4.0.1",
+ "node-int64": "^0.4.0",
+ "q": "^1.5.0",
+ "ws": "^5.2.3"
+ },
+ "engines": {
+ "node": ">= 10.18.0"
+ }
+ },
+ "node_modules/thrift/node_modules/ws": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz",
+ "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -10225,8 +10405,7 @@
},
"node_modules/tmpl": {
"version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="
+ "license": "BSD-3-Clause"
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
@@ -10501,8 +10680,7 @@
},
"node_modules/type-detect": {
"version": "4.0.8",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -10547,9 +10725,8 @@
"license": "MIT"
},
"node_modules/typeorm": {
- "version": "0.3.17",
- "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz",
- "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==",
+ "version": "0.3.16",
+ "license": "MIT",
"peer": true,
"dependencies": {
"@sqltools/formatter": "^1.2.5",
@@ -10654,8 +10831,7 @@
},
"node_modules/typeorm/node_modules/brace-expansion": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"balanced-match": "^1.0.0"
@@ -10663,8 +10839,7 @@
},
"node_modules/typeorm/node_modules/glob": {
"version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "license": "ISC",
"peer": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -10682,8 +10857,7 @@
},
"node_modules/typeorm/node_modules/minimatch": {
"version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
"peer": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -10694,8 +10868,7 @@
},
"node_modules/typeorm/node_modules/mkdirp": {
"version": "2.1.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
- "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
+ "license": "MIT",
"peer": true,
"bin": {
"mkdirp": "dist/cjs/src/bin.js"
@@ -10847,9 +11020,8 @@
},
"node_modules/v8-to-istanbul": {
"version": "9.1.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
- "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
"dev": true,
+ "license": "ISC",
"peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
@@ -10860,22 +11032,35 @@
"node": ">=10.12.0"
}
},
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "version": "0.3.18",
"dev": true,
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/v8-to-istanbul/node_modules/convert-source-map": {
"version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/validator": {
@@ -10885,6 +11070,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/varint": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
+ "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
+ },
"node_modules/vary": {
"version": "1.1.2",
"license": "MIT",
@@ -10899,12 +11089,16 @@
},
"node_modules/walker": {
"version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "license": "Apache-2.0",
"dependencies": {
"makeerror": "1.0.12"
}
},
+ "node_modules/wasm-brotli": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/wasm-brotli/-/wasm-brotli-2.0.2.tgz",
+ "integrity": "sha512-DgjRlpZz9z5br4TjQHSlDHRF9NIuGXHUj3AqO08koDCXz7EYzmPDb7T/6oar5UKLYgPp9Yxc2ImGpx4BMFwbNQ=="
+ },
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -11224,6 +11418,11 @@
"node": ">=0.4"
}
},
+ "node_modules/xxhash-wasm": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz",
+ "integrity": "sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A=="
+ },
"node_modules/y18n": {
"version": "5.0.8",
"license": "ISC",
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index c2030f78..61c4b2a3 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -32,6 +32,7 @@
},
"homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
"dependencies": {
+ "@dsnp/parquetjs": "^1.3.4",
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
From 45f4f4aa49477b1b7b6e4ec51097d6aa9956da64 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat
Date: Tue, 5 Sep 2023 13:22:31 -0500
Subject: [PATCH 011/137] ipfs service class util
---
.../apps/api/src/config/config.service.ts | 28 ++++++
.../libs/common/src/utils/ipfs.client.ts | 90 +++++++++++++++++++
services/content-watcher/package-lock.json | 29 +++++-
services/content-watcher/package.json | 4 +
4 files changed, 149 insertions(+), 2 deletions(-)
create mode 100644 services/content-watcher/libs/common/src/utils/ipfs.client.ts
diff --git a/services/content-watcher/apps/api/src/config/config.service.ts b/services/content-watcher/apps/api/src/config/config.service.ts
index ff789c50..c9df4853 100644
--- a/services/content-watcher/apps/api/src/config/config.service.ts
+++ b/services/content-watcher/apps/api/src/config/config.service.ts
@@ -7,6 +7,10 @@ import { ConfigService as NestConfigService } from '@nestjs/config';
import { ICapacityLimit } from '../interfaces/capacity-limit.interface';
export interface ConfigEnvironmentVariables {
+ IPFS_ENDPOINT: URL;
+ IPFS_GATEWAY_URL: URL;
+ IPFS_BASIC_AUTH_USER: string;
+ IPFS_BASIC_AUTH_SECRET: string;
REDIS_URL: URL;
FREQUENCY_URL: URL;
PROVIDER_ID: string;
@@ -77,4 +81,28 @@ export class ConfigService {
public getCapacityLimit(): ICapacityLimit {
return this.capacityLimit;
}
+
+ public getIpfsEndpoint(): string {
+ return this.nestConfigService.get('IPFS_ENDPOINT')!;
+ }
+
+ public getIpfsGatewayUrl(): string {
+ return this.nestConfigService.get('IPFS_GATEWAY_URL')!;
+ }
+
+ public getIpfsBasicAuthUser(): string {
+ return this.nestConfigService.get('IPFS_BASIC_AUTH_USER')!;
+ }
+
+ public getIpfsBasicAuthSecret(): string {
+ return this.nestConfigService.get('IPFS_BASIC_AUTH_SECRET')!;
+ }
+
+ public getIpfsCidPlaceholder(cid): string {
+ const gatewayUrl = this.getIpfsGatewayUrl();
+ if (!gatewayUrl || !gatewayUrl.includes('[CID]')) {
+ return `https://ipfs.io/ipfs/${cid}`;
+ }
+ return gatewayUrl.replace('[CID]', cid);
+ }
}
diff --git a/services/content-watcher/libs/common/src/utils/ipfs.client.ts b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
new file mode 100644
index 00000000..91159a53
--- /dev/null
+++ b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
@@ -0,0 +1,90 @@
+// ipfs.service.ts
+
+import { Injectable, Logger } from '@nestjs/common';
+import axios from 'axios';
+import FormData from 'form-data';
+import { extension as getExtension } from 'mime-types';
+import { CID } from 'multiformats/cid';
+import { blake2b256 as hasher } from '@multiformats/blake2/blake2b';
+import { base58btc } from 'multiformats/bases/base58';
+import { create } from 'multiformats/hashes/digest';
+import { ConfigService } from '../../../../apps/api/src/config/config.service';
+
+export interface FilePin {
+ cid: string;
+ cidBytes: Uint8Array;
+ fileName: string;
+ size: number;
+ hash: string;
+}
+
+@Injectable()
+export class IpfsService {
+ logger: Logger;
+
+ constructor(private readonly configService: ConfigService) {
+ this.logger = new Logger(IpfsService.name);
+ }
+
+ private async ipfsPinBuffer(filename: string, contentType: string, fileBuffer: Buffer): Promise {
+ const ipfsAdd = `${this.configService.getIpfsEndpoint()}/api/v0/add`;
+ const form = new FormData();
+ form.append('file', fileBuffer, {
+ filename,
+ contentType,
+ });
+
+ const ipfsAuthUser = this.configService.getIpfsBasicAuthUser();
+ const ipfsAuthSecret = this.configService.getIpfsBasicAuthSecret();
+ const ipfsAuth = ipfsAuthUser && ipfsAuthSecret ? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}` : '';
+
+ const headers = {
+ 'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`,
+ Accept: '*/*',
+ Connection: 'keep-alive',
+ authorization: ipfsAuth,
+ };
+
+ const response = await axios.post(ipfsAdd, form, { headers });
+
+ const { data } = response;
+ if (!data || !data.Hash || !data.Size) {
+ throw new Error(`Unable to pin file: ${filename}`);
+ }
+ const cid = CID.parse(data.Hash).toV1();
+
+ this.logger.debug(`Pinned file: ${filename} with size: ${data.Size} and cid: ${cid.toString(base58btc)}`);
+
+ return {
+ cid: cid.toString(base58btc),
+ cidBytes: cid.bytes,
+ fileName: data.Name,
+ size: data.Size,
+ hash: '',
+ };
+ }
+
+ public async ipfsPin(mimeType: string, file: Buffer): Promise {
+ const hash = await this.ipfsHashBuffer(file);
+ const extension = getExtension(mimeType);
+ if (extension === false) {
+ throw new Error(`unknown mimetype: ${mimeType}`);
+ }
+ const ipfs = await this.ipfsPinBuffer(`${hash}.${extension}`, mimeType, file);
+ return { ...ipfs, hash };
+ }
+
+ private async ipfsHashBuffer(fileBuffer: Buffer): Promise {
+ this.logger.debug(`Hashing file buffer with length: ${fileBuffer.length}`);
+ const hashed = await hasher.digest(fileBuffer);
+ const hash = create(hasher.code, hashed.bytes);
+ return base58btc.encode(hash.bytes);
+ }
+
+ public ipfsUrl(cid: string): string {
+ if (this.configService.getIpfsGatewayUrl().includes('[CID]')) {
+ return this.configService.getIpfsGatewayUrl().replace('[CID]', cid);
+ }
+ return `${this.configService.getIpfsGatewayUrl()}/ipfs/${cid}`;
+ }
+}
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index d6f3ede8..543aa1f9 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -13,6 +13,7 @@
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
+ "@multiformats/blake2": "^1.0.13",
"@nestjs/axios": "^2.0.0",
"@nestjs/bullmq": "^10.0.0",
"@nestjs/cli": "^10.1.14",
@@ -38,8 +39,11 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"crypto": "^1.0.1",
+ "form-data": "^4.0.0",
"ioredis": "^5.3.2",
"joi": "^17.9.1",
+ "mime-types": "^2.1.35",
+ "multiformats": "^9.9.0",
"rxjs": "^7.8.1",
"time-constants": "^1.0.3"
},
@@ -1389,6 +1393,15 @@
"node": ">=8"
}
},
+ "node_modules/@multiformats/blake2": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/@multiformats/blake2/-/blake2-1.0.13.tgz",
+ "integrity": "sha512-T1Kzya0wjj85CaVeRSpJ858EnSvW1pw94GSitxYf84VsNdv5XYbJ6QG8y26Ft1bVALzrUCmqkQrR53QHSyu6RA==",
+ "dependencies": {
+ "blakejs": "^1.1.1",
+ "multiformats": "^9.5.4"
+ }
+ },
"node_modules/@nestjs/axios": {
"version": "2.0.0",
"license": "MIT",
@@ -3988,6 +4001,11 @@
"node": ">= 6"
}
},
+ "node_modules/blakejs": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz",
+ "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ=="
+ },
"node_modules/bn.js": {
"version": "5.2.1",
"license": "MIT"
@@ -6221,7 +6239,8 @@
},
"node_modules/form-data": {
"version": "4.0.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -8346,7 +8365,8 @@
},
"node_modules/mime-types": {
"version": "2.1.35",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -8465,6 +8485,11 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/multiformats": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
+ "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
+ },
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 61c4b2a3..46b470d1 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -36,6 +36,7 @@
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
"@liaoliaots/nestjs-redis": "^9.0.5",
+ "@multiformats/blake2": "^1.0.13",
"@nestjs/axios": "^2.0.0",
"@nestjs/bullmq": "^10.0.0",
"@nestjs/cli": "^10.1.14",
@@ -61,8 +62,11 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"crypto": "^1.0.1",
+ "form-data": "^4.0.0",
"ioredis": "^5.3.2",
"joi": "^17.9.1",
+ "mime-types": "^2.1.35",
+ "multiformats": "^9.9.0",
"rxjs": "^7.8.1",
"time-constants": "^1.0.3"
},
From 5efa6bb8618291323a67d67063214c405fc3f210 Mon Sep 17 00:00:00 2001
From: Aramik
Date: Tue, 5 Sep 2023 16:51:16 -0700
Subject: [PATCH 012/137] init asset upload (#27)
* init asset upload
* more progress
* fixed wrong queue name bug
---
.../.github/workflows/build.yml | 2 +-
.../apps/api/src/api.controller.ts | 13 +-
.../apps/api/src/api.module.ts | 3 +
.../apps/api/src/api.service.ts | 120 +-
services/content-watcher/apps/api/src/main.ts | 3 +-
.../apps/api/test/app.e2e-spec.ts | 71 +-
.../asset_processor/asset.processor.module.ts | 57 +
.../asset.processor.service.ts | 49 +
.../src/batch_announcer/ipfs.announcer.ts | 8 +-
.../request.processor.module.ts | 60 +
.../request.processor.service.ts | 78 ++
.../apps/worker/src/worker.module.ts | 8 +-
.../libs/common/src/dtos/announcement.dto.ts | 1 +
.../libs/common/src/dtos/validation.dto.ts | 6 +
.../src/interfaces/asset-job.interface.ts | 12 +
.../src/interfaces/request-job.interface.ts | 1 +
.../libs/common/src/utils/ipfs.client.ts | 32 +-
.../libs/common/src/utils/ipfs.ts | 16 +
.../libs/common/src/utils/queues.ts | 4 +
.../libs/common/src/utils/redis.ts | 12 +
services/content-watcher/nest-cli.json | 18 +-
services/content-watcher/package-lock.json | 1071 +++++++++++++++--
services/content-watcher/package.json | 19 +-
services/content-watcher/tsconfig.build.json | 7 +
services/content-watcher/tsconfig.json | 14 +-
25 files changed, 1484 insertions(+), 201 deletions(-)
create mode 100644 services/content-watcher/apps/worker/src/asset_processor/asset.processor.module.ts
create mode 100644 services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
create mode 100644 services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
create mode 100644 services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
create mode 100644 services/content-watcher/libs/common/src/interfaces/asset-job.interface.ts
create mode 100644 services/content-watcher/libs/common/src/utils/ipfs.ts
create mode 100644 services/content-watcher/libs/common/src/utils/redis.ts
create mode 100644 services/content-watcher/tsconfig.build.json
diff --git a/services/content-watcher/.github/workflows/build.yml b/services/content-watcher/.github/workflows/build.yml
index 2a456a84..84a60224 100644
--- a/services/content-watcher/.github/workflows/build.yml
+++ b/services/content-watcher/.github/workflows/build.yml
@@ -56,4 +56,4 @@ jobs:
run: npm ci
- name: License Check
# List all the licenses and error out if it is not one of the supported licenses
- run: npx license-report --fields=name --fields=licenseType | jq 'map(select(.licenseType | IN("MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "BSD-2-Clause") | not)) | if length == 0 then halt else halt_error(1) end'
+ run: npx license-report --fields=name --fields=licenseType | jq 'map(select(.licenseType | IN("MIT", "Apache-2.0", "ISC", "BSD-3-Clause", "BSD-2-Clause", "(Apache-2.0 AND MIT)") | not)) | if length == 0 then halt else halt_error(1) end'
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index 12144e64..ea7518f6 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -1,10 +1,11 @@
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, ParseFilePipeBuilder, Post, Put, UploadedFiles, UseInterceptors } from '@nestjs/common';
-import { v4 as uuidv4 } from 'uuid';
import { FilesInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes } from '@nestjs/swagger';
+import { ApiService } from './api.service';
import {
AnnouncementResponseDto,
AnnouncementTypeDto,
+ AssetIncludedRequestDto,
BroadcastDto,
DSNP_VALID_MIME_TYPES,
DsnpContentHashParam,
@@ -16,7 +17,6 @@ import {
UpdateDto,
UploadResponseDto,
} from '../../../libs/common/src';
-import { ApiService } from './api.service';
@Controller('api')
export class ApiController {
@@ -59,21 +59,20 @@ export class ApiController {
files: // eslint-disable-next-line no-undef
Array,
): Promise {
- this.logger.log(`upload ${files.length}`);
- return {
- assetIds: files.map((_) => uuidv4()),
- };
+ return this.apiService.addAssets(files);
}
@Post('content/:userDsnpId/broadcast')
@HttpCode(202)
async broadcast(@Param() userDsnpId: DsnpUserIdParam, @Body() broadcastDto: BroadcastDto): Promise {
+ await this.apiService.validateAssets(broadcastDto as AssetIncludedRequestDto);
return this.apiService.enqueueRequest(AnnouncementTypeDto.BROADCAST, userDsnpId.userDsnpId, broadcastDto);
}
@Post('content/:userDsnpId/reply')
@HttpCode(202)
async reply(@Param() userDsnpId: DsnpUserIdParam, @Body() replyDto: ReplyDto): Promise {
+ await this.apiService.validateAssets(replyDto as AssetIncludedRequestDto);
return this.apiService.enqueueRequest(AnnouncementTypeDto.REPLY, userDsnpId.userDsnpId, replyDto);
}
@@ -86,6 +85,7 @@ export class ApiController {
@Put('content/:userDsnpId/:targetContentHash')
@HttpCode(202)
async update(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam, @Body() updateDto: UpdateDto): Promise {
+ await this.apiService.validateAssets(updateDto as AssetIncludedRequestDto);
return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto, targetContentHash.targetContentHash);
}
@@ -98,6 +98,7 @@ export class ApiController {
@Put('profile/:userDsnpId')
@HttpCode(202)
async profile(@Param() userDsnpId: DsnpUserIdParam, @Body() profileDto: ProfileDto): Promise {
+ await this.apiService.validateAssets(profileDto as AssetIncludedRequestDto);
return this.apiService.enqueueRequest(AnnouncementTypeDto.PROFILE, userDsnpId.userDsnpId, profileDto);
}
}
diff --git a/services/content-watcher/apps/api/src/api.module.ts b/services/content-watcher/apps/api/src/api.module.ts
index b7f45e39..83492bd7 100644
--- a/services/content-watcher/apps/api/src/api.module.ts
+++ b/services/content-watcher/apps/api/src/api.module.ts
@@ -20,6 +20,9 @@ import { ApiService } from './api.service';
BullModule.registerQueue({
name: QueueConstants.REQUEST_QUEUE_NAME,
}),
+ BullModule.registerQueue({
+ name: QueueConstants.ASSET_QUEUE_NAME,
+ }),
ConfigModule,
RedisModule.forRootAsync(
{
diff --git a/services/content-watcher/apps/api/src/api.service.ts b/services/content-watcher/apps/api/src/api.service.ts
index 5ca051c4..ee1abbc9 100644
--- a/services/content-watcher/apps/api/src/api.service.ts
+++ b/services/content-watcher/apps/api/src/api.service.ts
@@ -1,14 +1,36 @@
-import { Injectable, Logger } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bullmq';
+import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { Queue } from 'bullmq';
import { createHash } from 'crypto';
-import { AnnouncementResponseDto, AnnouncementTypeDto, IRequestJob, QueueConstants, RequestTypeDto } from '../../../libs/common/src';
+import { BulkJobOptions } from 'bullmq/dist/esm/interfaces';
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import Redis from 'ioredis';
+import { HttpErrorByCode } from '@nestjs/common/utils/http-error-by-code.util';
+import {
+ AnnouncementResponseDto,
+ AnnouncementTypeDto,
+ AssetIncludedRequestDto,
+ IRequestJob,
+ isImage,
+ QueueConstants,
+ RequestTypeDto,
+ UploadResponseDto,
+} from '../../../libs/common/src';
+import { calculateDsnpHash, calculateIpfsCID } from '../../../libs/common/src/utils/ipfs';
+import { IAssetJob, IAssetMetadata } from '../../../libs/common/src/interfaces/asset-job.interface';
+import { RedisUtils } from '../../../libs/common/src/utils/redis';
+import getAssetDataKey = RedisUtils.getAssetDataKey;
+import getAssetMetadataKey = RedisUtils.getAssetMetadataKey;
@Injectable()
export class ApiService {
private readonly logger: Logger;
- constructor(@InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue) {
+ constructor(
+ @InjectRedis() private redis: Redis,
+ @InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue,
+ @InjectQueue(QueueConstants.ASSET_QUEUE_NAME) private assetQueue: Queue,
+ ) {
this.logger = new Logger(this.constructor.name);
}
@@ -19,6 +41,7 @@ export class ApiService {
announcementType,
dsnpUserId,
targetContentHash,
+ dependencyAttempt: 0,
} as IRequestJob;
data.id = this.calculateJobId(data);
const job = await this.requestQueue.add(`Request Job - ${data.id}`, data, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 }); // TODO: should come from config
@@ -28,6 +51,97 @@ export class ApiService {
};
}
+ async validateAssets(content: AssetIncludedRequestDto): Promise {
+ const checkingList: Array<{ onlyImage: boolean; referenceId: string }> = [];
+ if (content.profile) {
+ content.profile.icon?.forEach((reference) => checkingList.push({ onlyImage: true, referenceId: reference.referenceId }));
+ } else if (content.content) {
+ content.content.assets?.forEach(
+ (asset) =>
+ asset.references?.forEach((reference) =>
+ checkingList.push({
+ onlyImage: false,
+ referenceId: reference.referenceId,
+ }),
+ ),
+ );
+ }
+
+ const redisResults = await Promise.all(checkingList.map((obj) => this.redis.get(getAssetMetadataKey(obj.referenceId))));
+ const errors: string[] = [];
+ redisResults.forEach((res, index) => {
+ if (res === null) {
+ errors.push(`${content.profile ? 'profile.icon' : 'content.assets'}.referenceId ${checkingList[index].referenceId} does not exist!`);
+ } else if (checkingList[index].onlyImage) {
+ // checks if attached asset is an image
+ const metadata: IAssetMetadata = JSON.parse(res);
+ if (!isImage(metadata.mimeType)) {
+ errors.push(`profile.icon.referenceId ${checkingList[index].referenceId} is not an image!`);
+ }
+ }
+ });
+ if (errors.length > 0) {
+ throw new HttpErrorByCode[400](errors);
+ }
+ }
+
+ // TODO: make all these operations transactional
+ // eslint-disable-next-line no-undef,class-methods-use-this
+ async addAssets(files: Array): Promise {
+ // calculate ipfs cid references
+ const referencePromises: Promise[] = files.map((file) => calculateIpfsCID(file.buffer));
+ const references = await Promise.all(referencePromises);
+
+ // add assets to redis
+ const redisDataOps = files.map((f, index) => this.redis.set(getAssetDataKey(references[index]), f.buffer));
+ const addedData = await Promise.all(redisDataOps);
+ this.logger.debug(addedData);
+
+ // add asset jobs to the queue
+ const jobs: any[] = [];
+ files.forEach((f, index) => {
+ jobs.push({
+ name: `Asset Job - ${references[index]}`,
+ data: {
+ ipfsCid: references[index],
+ contentLocation: getAssetDataKey(references[index]),
+ metadataLocation: getAssetMetadataKey(references[index]),
+ mimeType: f.mimetype,
+ } as IAssetJob,
+ opts: {
+ jobId: references[index],
+ removeOnFail: false,
+ removeOnComplete: true,
+ attempts: 3,
+ backoff: {
+ type: 'exponential',
+ delay: 10000,
+ },
+ } as BulkJobOptions,
+ });
+ });
+ const queuedJobs = await this.assetQueue.addBulk(jobs);
+ this.logger.debug(queuedJobs);
+
+ // add metadata to redis
+ const redisMetadataOps = files.map((f, index) =>
+ this.redis.set(
+ getAssetMetadataKey(references[index]),
+ JSON.stringify({
+ ipfsCid: references[index],
+ mimeType: f.mimetype,
+ createdOn: Date.now(),
+ } as IAssetMetadata),
+ ),
+ );
+ const addedMetadata = await Promise.all(redisMetadataOps);
+ this.logger.debug(addedMetadata);
+
+ return {
+ assetIds: references,
+ };
+ }
+
// eslint-disable-next-line class-methods-use-this
calculateJobId(jobWithoutId: IRequestJob): string {
const stringVal = JSON.stringify(jobWithoutId);
diff --git a/services/content-watcher/apps/api/src/main.ts b/services/content-watcher/apps/api/src/main.ts
index 8cba5acd..719af90b 100644
--- a/services/content-watcher/apps/api/src/main.ts
+++ b/services/content-watcher/apps/api/src/main.ts
@@ -1,6 +1,7 @@
import { NestFactory } from '@nestjs/core';
-import { Logger, ValidationPipe } from '@nestjs/common';
+import { BadRequestException, Logger, ValidationPipe } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
+import { ValidationError } from 'class-validator';
import { ApiModule } from './api.module';
import { initSwagger } from './config/swagger_config';
diff --git a/services/content-watcher/apps/api/test/app.e2e-spec.ts b/services/content-watcher/apps/api/test/app.e2e-spec.ts
index b6786248..b763942c 100644
--- a/services/content-watcher/apps/api/test/app.e2e-spec.ts
+++ b/services/content-watcher/apps/api/test/app.e2e-spec.ts
@@ -9,7 +9,7 @@ import { ApiModule } from '../src/api.module';
describe('AppController E2E request verification!', () => {
let app: INestApplication;
let module: TestingModule;
- const validlocation = {
+ const validLocation = {
name: 'name of location',
accuracy: 97,
altitude: 10,
@@ -28,36 +28,18 @@ describe('AppController E2E request verification!', () => {
name: '#taggedUser',
},
];
- const validContent = {
+ const validContentNoAssets = {
content: 'test broadcast message',
published: '1970-01-01T00:00:00+00:00',
- assets: [
- {
- type: 'image',
- name: 'image asset',
- references: [
- {
- referenceId: 'reference-id-1',
- height: 123,
- width: 321,
- },
- ],
- },
- {
- type: 'link',
- name: 'link asset',
- href: 'http://example.com',
- },
- ],
name: 'name of note content',
tag: validTags,
- location: validlocation,
+ location: validLocation,
};
- const validBroadCast = {
- content: validContent,
+ const validBroadCastNoAssets = {
+ content: validContentNoAssets,
};
- const validReply = {
- content: validContent,
+ const validReplyNoAssets = {
+ content: validContentNoAssets,
inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
const validReaction = {
@@ -65,19 +47,12 @@ describe('AppController E2E request verification!', () => {
apply: 5,
inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
- const validProfile = {
- icon: [
- {
- referenceId: 'reference-id-1',
- height: 123,
- width: 321,
- },
- ],
+ const validProfileNoAssets = {
summary: 'profile summary',
published: '1970-01-01T00:00:00+00:00',
name: 'name of profile content',
tag: validTags,
- location: validlocation,
+ location: validLocation,
};
beforeEach(async () => {
@@ -102,7 +77,7 @@ describe('AppController E2E request verification!', () => {
const invalidDsnpUserId = '2gsjhdaj';
return request(app.getHttpServer())
.post(`/api/content/${invalidDsnpUserId}/broadcast`)
- .send(validBroadCast)
+ .send(validBroadCastNoAssets)
.expect(400)
.expect((res) => expect(res.text).toContain('must be a number string'));
});
@@ -117,10 +92,10 @@ describe('AppController E2E request verification!', () => {
});
describe('(POST) /api/content/:dsnpUserId/broadcast', () => {
- it('valid request should work!', () =>
+ it('valid request without assets should work!', () =>
request(app.getHttpServer())
.post(`/api/content/123/broadcast`)
- .send(validBroadCast)
+ .send(validBroadCastNoAssets)
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
@@ -371,10 +346,10 @@ describe('AppController E2E request verification!', () => {
});
describe('(POST) /api/content/:dsnpUserId/reply', () => {
- it('valid request should work!', () =>
+ it('valid request without assets should work!', () =>
request(app.getHttpServer())
.post(`/api/content/123/reply`)
- .send(validReply)
+ .send(validReplyNoAssets)
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
@@ -391,7 +366,7 @@ describe('AppController E2E request verification!', () => {
request(app.getHttpServer())
.post(`/api/content/123/reply`)
.send({
- content: validContent,
+ content: validContentNoAssets,
})
.expect(400)
.expect((res) => expect(res.text).toContain('inReplyTo must be a string')));
@@ -400,7 +375,7 @@ describe('AppController E2E request verification!', () => {
request(app.getHttpServer())
.post(`/api/content/123/reply`)
.send({
- content: validContent,
+ content: validContentNoAssets,
inReplyTo: 'shgdjas72gsjajasa',
})
.expect(400)
@@ -447,12 +422,12 @@ describe('AppController E2E request verification!', () => {
});
describe('(PUT) /api/content/:dsnpUserId/:contentHash', () => {
- it('valid request should work!', () =>
+ it('valid request without assets should work!', () =>
request(app.getHttpServer())
.put(`/api/content/123/0x7653423447AF`)
.send({
targetAnnouncementType: 'broadcast',
- content: validContent,
+ content: validContentNoAssets,
})
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
@@ -462,7 +437,7 @@ describe('AppController E2E request verification!', () => {
.put(`/api/content/123/0x7653423447AF`)
.send({
targetAnnouncementType: 'invalid',
- content: validContent,
+ content: validContentNoAssets,
})
.expect(400)
.expect((res) => expect(res.text).toContain('targetAnnouncementType must be one of the following values')));
@@ -477,11 +452,11 @@ describe('AppController E2E request verification!', () => {
});
describe('(PUT) /api/profile/:userDsnpId', () => {
- it('valid request should work!', () =>
+ it('valid request without assets should work!', () =>
request(app.getHttpServer())
.put(`/api/profile/123`)
.send({
- profile: validProfile,
+ profile: validProfileNoAssets,
})
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
@@ -527,14 +502,14 @@ describe('AppController E2E request verification!', () => {
it('valid request should work!', () =>
request(app.getHttpServer())
.put(`/api/asset/upload`)
- .attach('files', Buffer.from(validContent.toString()), 'image.jpg')
+ .attach('files', Buffer.from(validContentNoAssets.toString()), 'image.jpg')
.expect(202)
.expect((res) => expect(res.text).toContain('assetIds')));
it('invalid mime should fail', () =>
request(app.getHttpServer())
.put(`/api/asset/upload`)
- .attach('files', Buffer.from(validContent.toString()), 'doc.txt')
+ .attach('files', Buffer.from(validContentNoAssets.toString()), 'doc.txt')
.expect(422)
.expect((res) => expect(res.text).toContain('expected type is')));
});
diff --git a/services/content-watcher/apps/worker/src/asset_processor/asset.processor.module.ts b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.module.ts
new file mode 100644
index 00000000..22bd2282
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.module.ts
@@ -0,0 +1,57 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { BullModule } from '@nestjs/bullmq';
+import { Module } from '@nestjs/common';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { ConfigModule } from '../../../api/src/config/config.module';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { QueueConstants } from '../../../../libs/common/src';
+import { AssetProcessorService } from './asset.processor.service';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+@Module({
+ imports: [
+ ConfigModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ BullModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => {
+ // Note: BullMQ doesn't honor a URL for the Redis connection, and
+ // JS URL doesn't parse 'redis://' as a valid protocol, so we fool
+ // it by changing the URL to use 'http://' in order to parse out
+ // the host, port, username, password, etc.
+ // We could pass REDIS_HOST, REDIS_PORT, etc, in the environment, but
+ // trying to keep the # of environment variables from proliferating
+ const url = new URL(configService.redisUrl.toString().replace(/^redis[s]*/, 'http'));
+ const { hostname, port, username, password, pathname } = url;
+ return {
+ connection: {
+ host: hostname || undefined,
+ port: port ? Number(port) : undefined,
+ username: username || undefined,
+ password: password || undefined,
+ db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
+ },
+ };
+ },
+ inject: [ConfigService],
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.ASSET_QUEUE_NAME,
+ }),
+ ],
+ providers: [AssetProcessorService, IpfsService],
+ exports: [BullModule, AssetProcessorService, IpfsService],
+})
+export class AssetProcessorModule {}
diff --git a/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
new file mode 100644
index 00000000..045850c0
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
@@ -0,0 +1,49 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
+import { Injectable, Logger } from '@nestjs/common';
+import { Job } from 'bullmq';
+import Redis from 'ioredis';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { QueueConstants } from '../../../../libs/common/src';
+import { IAssetJob } from '../../../../libs/common/src/interfaces/asset-job.interface';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+@Injectable()
+@Processor(QueueConstants.ASSET_QUEUE_NAME)
+export class AssetProcessorService extends WorkerHost {
+ private logger: Logger;
+
+ constructor(
+ @InjectRedis() private redis: Redis,
+ private configService: ConfigService,
+ private ipfsService: IpfsService,
+ ) {
+ super();
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ async process(job: Job): Promise {
+ this.logger.log(`Processing job ${job.id} of type ${job.name}`);
+ this.logger.debug(job.asJSON());
+ const redisResults = await this.redis.getBuffer(job.data.contentLocation);
+ if (!redisResults) {
+ throw new Error(`Content stored in ${job.data.contentLocation} does not exist!`);
+ }
+ const pinned = await this.ipfsService.ipfsPin(job.data.mimeType, redisResults, false);
+ this.logger.log(pinned);
+ if (job.data.ipfsCid !== pinned.cid) {
+ throw new Error(`Cid does not match ${job.data.ipfsCid} != ${pinned.cid}`);
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ async onCompleted(job: Job) {
+ this.logger.log(`completed ${job.id}`);
+ const secondsPassed = Math.round((Date.now() - job.timestamp) / 1000);
+ const expectedSecondsToExpire = 5 * 60; // TODO: get from config
+ const secondsToExpire = Math.max(0, expectedSecondsToExpire - secondsPassed);
+ const result = await this.redis.pipeline().del(job.data.contentLocation).expire(job.data.metadataLocation, secondsToExpire, 'LT').exec();
+ this.logger.debug(result);
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
index bc94d958..f548271e 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
@@ -1,6 +1,4 @@
import { Injectable, Logger } from '@nestjs/common';
-import { EventEmitter2 } from '@nestjs/event-emitter';
-import { BlockchainService } from '../blockchain/blockchain.service';
import { ConfigService } from '../../../api/src/config/config.service';
import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
@@ -8,11 +6,7 @@ import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interf
export class IPFSAnnouncer {
private logger: Logger;
- constructor(
- private configService: ConfigService,
- private blockchainService: BlockchainService,
- private eventEmitter: EventEmitter2,
- ) {
+ constructor(private configService: ConfigService) {
this.logger = new Logger(IPFSAnnouncer.name);
}
diff --git a/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts b/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
new file mode 100644
index 00000000..e50fdff1
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
@@ -0,0 +1,60 @@
+/*
+https://docs.nestjs.com/modules
+*/
+
+import { BullModule } from '@nestjs/bullmq';
+import { Module } from '@nestjs/common';
+import { RedisModule } from '@liaoliaots/nestjs-redis';
+import { ConfigModule } from '../../../api/src/config/config.module';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { QueueConstants } from '../../../../libs/common/src';
+import { RequestProcessorService } from './request.processor.service';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+@Module({
+ imports: [
+ ConfigModule,
+ RedisModule.forRootAsync(
+ {
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ config: [{ url: configService.redisUrl.toString() }],
+ }),
+ inject: [ConfigService],
+ },
+ true, // isGlobal
+ ),
+ BullModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => {
+ // Note: BullMQ doesn't honor a URL for the Redis connection, and
+ // JS URL doesn't parse 'redis://' as a valid protocol, so we fool
+ // it by changing the URL to use 'http://' in order to parse out
+ // the host, port, username, password, etc.
+ // We could pass REDIS_HOST, REDIS_PORT, etc, in the environment, but
+ // trying to keep the # of environment variables from proliferating
+ const url = new URL(configService.redisUrl.toString().replace(/^redis[s]*/, 'http'));
+ const { hostname, port, username, password, pathname } = url;
+ return {
+ connection: {
+ host: hostname || undefined,
+ port: port ? Number(port) : undefined,
+ username: username || undefined,
+ password: password || undefined,
+ db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
+ },
+ };
+ },
+ inject: [ConfigService],
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.ASSET_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.REQUEST_QUEUE_NAME,
+ }),
+ ],
+ providers: [RequestProcessorService, IpfsService],
+ exports: [BullModule, RequestProcessorService, IpfsService],
+})
+export class RequestProcessorModule {}
diff --git a/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
new file mode 100644
index 00000000..1abfca4f
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
@@ -0,0 +1,78 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
+import { Injectable, Logger } from '@nestjs/common';
+import { DelayedError, Job } from 'bullmq';
+import Redis from 'ioredis';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { AnnouncementTypeDto, BroadcastDto, IRequestJob, ProfileDto, QueueConstants, ReplyDto, UpdateDto } from '../../../../libs/common/src';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+@Injectable()
+@Processor(QueueConstants.REQUEST_QUEUE_NAME)
+export class RequestProcessorService extends WorkerHost {
+ private logger: Logger;
+
+ constructor(
+ @InjectRedis() private redis: Redis,
+ private configService: ConfigService,
+ private ipfsService: IpfsService,
+ ) {
+ super();
+ this.logger = new Logger(this.constructor.name);
+ }
+
+ async process(job: Job): Promise {
+ this.logger.log(`Processing job ${job.id} of type ${job.name}`);
+ this.logger.debug(job.asJSON());
+ const assets = this.getAssetReferencesFromRequestJob(job.data);
+
+ const pinnedAssets = assets.map((cid) => this.ipfsService.getPinned(cid));
+ const pinnedResult = await Promise.all(pinnedAssets);
+ this.logger.debug(pinnedResult);
+ // if any of assets does not exists delay the job for a future attempt
+ if (pinnedResult.some((buffer) => !buffer)) {
+ await this.delayJobAndIncrementAttempts(job);
+ } else {
+ // TODO: create attachments from assets
+ }
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ @OnWorkerEvent('completed')
+ onCompleted() {}
+
+ // eslint-disable-next-line class-methods-use-this
+ private getAssetReferencesFromRequestJob(job: IRequestJob): Array {
+ const assets: string[] = [];
+ // eslint-disable-next-line default-case
+ switch (job.announcementType) {
+ case AnnouncementTypeDto.BROADCAST:
+ (job.content as BroadcastDto).content.assets?.forEach((a) => a.references?.forEach((r) => assets.push(r.referenceId)));
+ break;
+ case AnnouncementTypeDto.REPLY:
+ (job.content as ReplyDto).content.assets?.forEach((a) => a.references?.forEach((r) => assets.push(r.referenceId)));
+ break;
+ case AnnouncementTypeDto.UPDATE:
+ (job.content as UpdateDto).content.assets?.forEach((a) => a.references?.forEach((r) => assets.push(r.referenceId)));
+ break;
+ case AnnouncementTypeDto.PROFILE:
+ (job.content as ProfileDto).profile.icon?.forEach((r) => assets.push(r.referenceId));
+ }
+ return assets;
+ }
+
+ // eslint-disable-next-line class-methods-use-this
+ private async delayJobAndIncrementAttempts(job: Job) {
+ const { data } = job;
+ data.dependencyAttempt += 1;
+ if (data.dependencyAttempt <= 3) {
+ // attempts 10 seconds, 20 seconds, 40 seconds
+ const delayedTime = 2 ** data.dependencyAttempt * 5 * 1000;
+ await job.moveToDelayed(Date.now() + delayedTime, job.token); // TODO: get from config
+ await job.update(data);
+ throw new DelayedError();
+ } else {
+ throw new Error('Dependency failed!');
+ }
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/worker.module.ts b/services/content-watcher/apps/worker/src/worker.module.ts
index ea631a37..62ce5776 100644
--- a/services/content-watcher/apps/worker/src/worker.module.ts
+++ b/services/content-watcher/apps/worker/src/worker.module.ts
@@ -13,6 +13,10 @@ import { BatchAnnouncementService } from './batch_announcer/batch.announcer.serv
import { BatchAnnouncerModule } from './batch_announcer/batch.announcer.module';
import { StatusMonitorModule } from './monitor/status.monitor.module';
import { StatusMonitoringService } from './monitor/status.monitor.service';
+import { AssetProcessorModule } from './asset_processor/asset.processor.module';
+import { AssetProcessorService } from './asset_processor/asset.processor.service';
+import { RequestProcessorModule } from './request_processor/request.processor.module';
+import { RequestProcessorService } from './request_processor/request.processor.service';
@Module({
imports: [
@@ -51,7 +55,9 @@ import { StatusMonitoringService } from './monitor/status.monitor.service';
BlockchainModule,
BatchAnnouncerModule,
StatusMonitorModule,
+ AssetProcessorModule,
+ RequestProcessorModule,
],
- providers: [BatchAnnouncementService, ConfigService, WorkerService, PublishingService, StatusMonitoringService],
+ providers: [BatchAnnouncementService, ConfigService, WorkerService, PublishingService, StatusMonitoringService, AssetProcessorService, RequestProcessorService],
})
export class WorkerModule {}
diff --git a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
index 857d463f..d9464527 100644
--- a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
@@ -65,3 +65,4 @@ export class ProfileDto {
}
export type RequestTypeDto = BroadcastDto | ReplyDto | ReactionDto | UpdateDto | ProfileDto;
+export type AssetIncludedRequestDto = BroadcastDto & ReplyDto & UpdateDto & ProfileDto;
diff --git a/services/content-watcher/libs/common/src/dtos/validation.dto.ts b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
index b867b109..3b2e0fee 100644
--- a/services/content-watcher/libs/common/src/dtos/validation.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
@@ -30,3 +30,9 @@ export const DURATION_REGEX = /^-?P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([
*/
export const DSNP_VALID_MIME_TYPES =
/(image\/jpeg|image\/png|image\/svg\+xml|image\/webp|image\/gif|video\/mpeg|video\/ogg|video\/webm|video\/H256|video\/mp4|audio\/mpeg|audio\/ogg|audio\/webm)$/;
+/**
+ * checks to see if provided mime type is an image
+ */
+export function isImage(mimeType: string): boolean {
+ return mimeType != null && mimeType.toLowerCase().startsWith('image');
+}
diff --git a/services/content-watcher/libs/common/src/interfaces/asset-job.interface.ts b/services/content-watcher/libs/common/src/interfaces/asset-job.interface.ts
new file mode 100644
index 00000000..3da2dc91
--- /dev/null
+++ b/services/content-watcher/libs/common/src/interfaces/asset-job.interface.ts
@@ -0,0 +1,12 @@
+export interface IAssetJob {
+ ipfsCid: string;
+ mimeType: string;
+ contentLocation: string;
+ metadataLocation: string;
+}
+
+export interface IAssetMetadata {
+ ipfsCid: string;
+ mimeType: string;
+ createdOn: number;
+}
diff --git a/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
index 0798cd4a..55593ec5 100644
--- a/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
+++ b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
@@ -7,4 +7,5 @@ export interface IRequestJob {
dsnpUserId: string;
targetContentHash?: string;
content?: RequestTypeDto;
+ dependencyAttempt: number;
}
diff --git a/services/content-watcher/libs/common/src/utils/ipfs.client.ts b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
index 91159a53..0729d642 100644
--- a/services/content-watcher/libs/common/src/utils/ipfs.client.ts
+++ b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
@@ -8,6 +8,7 @@ import { CID } from 'multiformats/cid';
import { blake2b256 as hasher } from '@multiformats/blake2/blake2b';
import { base58btc } from 'multiformats/bases/base58';
import { create } from 'multiformats/hashes/digest';
+import { randomUUID } from 'crypto';
import { ConfigService } from '../../../../apps/api/src/config/config.service';
export interface FilePin {
@@ -53,10 +54,10 @@ export class IpfsService {
}
const cid = CID.parse(data.Hash).toV1();
- this.logger.debug(`Pinned file: ${filename} with size: ${data.Size} and cid: ${cid.toString(base58btc)}`);
+ this.logger.debug(`Pinned file: ${filename} with size: ${data.Size} and cid: ${cid}`);
return {
- cid: cid.toString(base58btc),
+ cid: cid.toString(),
cidBytes: cid.bytes,
fileName: data.Name,
size: data.Size,
@@ -64,14 +65,33 @@ export class IpfsService {
};
}
- public async ipfsPin(mimeType: string, file: Buffer): Promise {
- const hash = await this.ipfsHashBuffer(file);
+ public async ipfsPin(mimeType: string, file: Buffer, calculateDsnpHash: boolean = true): Promise {
+ const fileName = calculateDsnpHash ? await this.ipfsHashBuffer(file) : randomUUID().toString();
const extension = getExtension(mimeType);
if (extension === false) {
throw new Error(`unknown mimetype: ${mimeType}`);
}
- const ipfs = await this.ipfsPinBuffer(`${hash}.${extension}`, mimeType, file);
- return { ...ipfs, hash };
+ const ipfs = await this.ipfsPinBuffer(`${fileName}.${extension}`, mimeType, file);
+ return { ...ipfs, hash: calculateDsnpHash ? fileName : '' };
+ }
+
+ // TODO: bugfix: when the cid does not exist the endpoint will get stuck indefinitely
+ public async getPinned(cid: string): Promise {
+ const ipfsGet = `${this.configService.getIpfsEndpoint()}/api/v0/cat?arg=${cid}`;
+ const ipfsAuthUser = this.configService.getIpfsBasicAuthUser();
+ const ipfsAuthSecret = this.configService.getIpfsBasicAuthSecret();
+ const ipfsAuth = ipfsAuthUser && ipfsAuthSecret ? `Basic ${Buffer.from(`${ipfsAuthUser}:${ipfsAuthSecret}`).toString('base64')}` : '';
+
+ const headers = {
+ Accept: '*/*',
+ Connection: 'keep-alive',
+ authorization: ipfsAuth,
+ };
+
+ const response = await axios.post(ipfsGet, null, { headers, responseType: 'arraybuffer' });
+
+ const { data } = response;
+ return data;
}
private async ipfsHashBuffer(fileBuffer: Buffer): Promise {
diff --git a/services/content-watcher/libs/common/src/utils/ipfs.ts b/services/content-watcher/libs/common/src/utils/ipfs.ts
new file mode 100644
index 00000000..48e5648c
--- /dev/null
+++ b/services/content-watcher/libs/common/src/utils/ipfs.ts
@@ -0,0 +1,16 @@
+import * as ipfsHash from 'ipfs-only-hash';
+import { blake2b256 } from '@multiformats/blake2/blake2b';
+import { create } from 'multiformats/hashes/digest';
+import { CID } from 'multiformats';
+import { base58btc } from 'multiformats/bases/base58';
+
+export async function calculateIpfsCID(buffer: Buffer): Promise {
+ const v0 = await ipfsHash.of(buffer);
+ return CID.parse(v0).toV1().toString();
+}
+
+export const calculateDsnpHash = async (fileBuffer: Buffer): Promise => {
+ const hash = await blake2b256.digest(fileBuffer);
+ const digest = create(blake2b256.code, hash.bytes);
+ return base58btc.encode(digest.bytes);
+};
diff --git a/services/content-watcher/libs/common/src/utils/queues.ts b/services/content-watcher/libs/common/src/utils/queues.ts
index 2db48f4a..270e6eed 100644
--- a/services/content-watcher/libs/common/src/utils/queues.ts
+++ b/services/content-watcher/libs/common/src/utils/queues.ts
@@ -1,6 +1,10 @@
import { AnnouncementTypeDto } from '../dtos/common.dto';
export namespace QueueConstants {
+ /**
+ * Name of the queue that has all incoming asset uploads
+ */
+ export const ASSET_QUEUE_NAME = 'assetQueue';
/**
* Name of the queue that has all incoming requests
*/
diff --git a/services/content-watcher/libs/common/src/utils/redis.ts b/services/content-watcher/libs/common/src/utils/redis.ts
new file mode 100644
index 00000000..c16f4169
--- /dev/null
+++ b/services/content-watcher/libs/common/src/utils/redis.ts
@@ -0,0 +1,12 @@
+export namespace RedisUtils {
+ const ASSET_DATA_KEY_PREFIX = 'asset::data';
+ const ASSET_METADATA_KEY_PREFIX = 'asset::metadata';
+
+ export function getAssetDataKey(assetId: string) {
+ return `${ASSET_DATA_KEY_PREFIX}:${assetId}`;
+ }
+
+ export function getAssetMetadataKey(assetId: string) {
+ return `${ASSET_METADATA_KEY_PREFIX}:${assetId}`;
+ }
+}
diff --git a/services/content-watcher/nest-cli.json b/services/content-watcher/nest-cli.json
index dca51c9f..3478f17a 100644
--- a/services/content-watcher/nest-cli.json
+++ b/services/content-watcher/nest-cli.json
@@ -1,4 +1,14 @@
{
+ "$schema": "https://json.schemastore.org/nest-cli",
+ "collection": "@nestjs/schematics",
+ "sourceRoot": "apps/api/src",
+ "compilerOptions": {
+ "deleteOutDir": true,
+ "webpack": true,
+ "tsConfigPath": "apps/api/tsconfig.app.json"
+ },
+ "monorepo": true,
+ "root": "apps/api",
"projects": {
"common": {
"type": "library",
@@ -27,11 +37,5 @@
"tsConfigPath": "apps/worker/tsconfig.app.json"
}
}
- },
- "compilerOptions": {
- "tsConfigPath": "apps/api/tsconfig.app.json"
- },
- "monorepo": true,
- "root": "apps/api",
- "sourceRoot": "apps/api/src"
+ }
}
\ No newline at end of file
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index 543aa1f9..db2c7091 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -38,9 +38,9 @@
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
- "crypto": "^1.0.1",
"form-data": "^4.0.0",
"ioredis": "^5.3.2",
+ "ipfs-only-hash": "^4.0.0",
"joi": "^17.9.1",
"mime-types": "^2.1.35",
"multiformats": "^9.9.0",
@@ -67,8 +67,12 @@
"eslint-plugin-nestjs": "^1.2.3",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
+ "jest": "^29.5.0",
"license-report": "^6.4.0",
+ "prettier": "^3.0.2",
+ "source-map-support": "^0.5.21",
"supertest": "^6.3.3",
+ "trace-unhandled": "^2.0.1",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
@@ -212,6 +216,11 @@
"node": ">=12.0.0"
}
},
+ "node_modules/@assemblyscript/loader": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz",
+ "integrity": "sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA=="
+ },
"node_modules/@babel/code-frame": {
"version": "7.22.5",
"license": "MIT",
@@ -742,8 +751,7 @@
"node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@colors/colors": {
"version": "1.5.0",
@@ -988,7 +996,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/types": "^29.5.0",
"@types/node": "*",
@@ -1005,7 +1012,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/console": "^29.5.0",
"@jest/reporters": "^29.5.0",
@@ -1114,7 +1120,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
"@jest/console": "^29.5.0",
@@ -1157,7 +1162,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.0.0"
}
@@ -1165,14 +1169,12 @@
"node_modules/@jest/reporters/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
@@ -1192,7 +1194,6 @@
"version": "29.4.3",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.15",
"callsites": "^3.0.0",
@@ -1206,7 +1207,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.0.0"
}
@@ -1214,14 +1214,12 @@
"node_modules/@jest/source-map/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
@@ -1231,7 +1229,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/console": "^29.5.0",
"@jest/types": "^29.5.0",
@@ -1246,7 +1243,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/test-result": "^29.5.0",
"graceful-fs": "^4.2.9",
@@ -1393,6 +1389,11 @@
"node": ">=8"
}
},
+ "node_modules/@multiformats/base-x": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz",
+ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw=="
+ },
"node_modules/@multiformats/blake2": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/@multiformats/blake2/-/blake2-1.0.13.tgz",
@@ -2474,6 +2475,60 @@
"node": ">=16"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
"node_modules/@redis/bloom": {
"version": "1.2.0",
"license": "MIT",
@@ -2651,7 +2706,6 @@
"version": "7.20.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/parser": "^7.20.7",
"@babel/types": "^7.20.7",
@@ -2664,7 +2718,6 @@
"version": "7.6.4",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/types": "^7.0.0"
}
@@ -2673,7 +2726,6 @@
"version": "7.4.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/parser": "^7.1.0",
"@babel/types": "^7.0.0"
@@ -2824,6 +2876,11 @@
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
},
+ "node_modules/@types/minimist": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
+ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ=="
+ },
"node_modules/@types/multer": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
@@ -2845,6 +2902,11 @@
"@types/node": "*"
}
},
+ "node_modules/@types/normalize-package-data": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
+ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
+ },
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@@ -3790,6 +3852,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -3835,7 +3905,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/transform": "^29.5.0",
"@types/babel__core": "^7.1.14",
@@ -3870,7 +3939,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/template": "^7.3.3",
"@babel/types": "^7.3.3",
@@ -3906,7 +3974,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"babel-plugin-jest-hoist": "^29.5.0",
"babel-preset-current-node-syntax": "^1.0.0"
@@ -4189,7 +4256,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
@@ -4355,6 +4421,30 @@
"node": ">=6"
}
},
+ "node_modules/camelcase-keys": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+ "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "map-obj": "^4.0.0",
+ "quick-lru": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/camelcase-keys/node_modules/quick-lru": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
+ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/caniuse-lite": {
"version": "1.0.30001502",
"funding": [
@@ -4391,7 +4481,6 @@
"version": "1.0.2",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=10"
}
@@ -4457,11 +4546,34 @@
"node": ">=8"
}
},
+ "node_modules/cids": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/cids/-/cids-1.1.9.tgz",
+ "integrity": "sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "multibase": "^4.0.1",
+ "multicodec": "^3.0.1",
+ "multihashes": "^4.0.1",
+ "uint8arrays": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0",
+ "npm": ">=3.0.0"
+ }
+ },
+ "node_modules/cids/node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
"node_modules/cjs-module-lexer": {
"version": "1.2.3",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/class-transformer": {
"version": "0.5.1",
@@ -4606,7 +4718,6 @@
"version": "4.6.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"iojs": ">= 1.0.0",
"node": ">= 0.12.0"
@@ -4615,8 +4726,7 @@
"node_modules/collect-v8-coverage": {
"version": "1.0.1",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/color-convert": {
"version": "2.0.1",
@@ -4826,12 +4936,6 @@
"node": ">= 8"
}
},
- "node_modules/crypto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
- "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
- "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
- },
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"license": "MIT",
@@ -4869,6 +4973,37 @@
}
}
},
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decamelize-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+ "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+ "dependencies": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decamelize-keys/node_modules/map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/decompress-response": {
"version": "6.0.0",
"dev": true,
@@ -4897,8 +5032,7 @@
"node_modules/dedent": {
"version": "0.7.0",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/deep-extend": {
"version": "0.6.0",
@@ -5030,7 +5164,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=8"
}
@@ -5119,7 +5252,6 @@
"version": "0.13.1",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -5163,6 +5295,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/err-code": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz",
+ "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA=="
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"license": "MIT",
@@ -5876,7 +6013,6 @@
"node_modules/exit": {
"version": "0.1.2",
"dev": true,
- "peer": true,
"engines": {
"node": ">= 0.8.0"
}
@@ -6210,6 +6346,19 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/foreground-child": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/fork-ts-checker-webpack-plugin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz",
@@ -6239,8 +6388,7 @@
},
"node_modules/form-data": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -6587,6 +6735,14 @@
"uglify-js": "^3.1.4"
}
},
+ "node_modules/hard-rejection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/has": {
"version": "1.0.3",
"license": "MIT",
@@ -6665,6 +6821,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/haxec": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/haxec/-/haxec-2.0.1.tgz",
+ "integrity": "sha512-2DaSqGZIzgVkZ4YFHbk9Su0Q6gm7YbzNX9njOHK/D/XklOdvgTemsPmjcyExlLdkl7lRlNIW0Wxo6niVfpWedw==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^2.0.0",
+ "spawn-wrap": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/hexoid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
@@ -6682,11 +6851,21 @@
"node": "*"
}
},
+ "node_modules/hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/html-escaper": {
"version": "2.0.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/http-cache-semantics": {
"version": "4.1.1",
@@ -6781,7 +6960,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0"
@@ -6803,6 +6981,14 @@
"node": ">=0.8.19"
}
},
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/inflight": {
"version": "1.0.6",
"license": "ISC",
@@ -6863,6 +7049,17 @@
"resolved": "https://registry.npmjs.org/int53/-/int53-0.2.4.tgz",
"integrity": "sha512-a5jlKftS7HUOhkUyYD7j2sJ/ZnvWiNlZS1ldR+g1ifQ+/UuZXIE+YTc/lK1qGj/GwAU5F8Z0e1eVq2t1J5Ob2g=="
},
+ "node_modules/interface-ipld-format": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/interface-ipld-format/-/interface-ipld-format-1.0.1.tgz",
+ "integrity": "sha512-WV/ar+KQJVoQpqRDYdo7YPGYIUHJxCuOEhdvsRpzLqoOIVCqPKdMMYmsLL1nCRsF3yYNio+PAJbCKiv6drrEAg==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "cids": "^1.1.6",
+ "multicodec": "^3.0.1",
+ "multihashes": "^4.0.2"
+ }
+ },
"node_modules/internal-slot": {
"version": "1.0.5",
"dev": true,
@@ -6913,6 +7110,208 @@
"node": ">= 0.10"
}
},
+ "node_modules/ipfs-only-hash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/ipfs-only-hash/-/ipfs-only-hash-4.0.0.tgz",
+ "integrity": "sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA==",
+ "dependencies": {
+ "ipfs-unixfs-importer": "^7.0.1",
+ "meow": "^9.0.0"
+ },
+ "bin": {
+ "ipfs-only-hash": "cli.js"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/hamt-sharding": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-2.0.1.tgz",
+ "integrity": "sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==",
+ "dependencies": {
+ "sparse-array": "^1.3.1",
+ "uint8arrays": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0",
+ "npm": ">=6.0.0"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/hamt-sharding/node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/ipfs-unixfs": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-4.0.3.tgz",
+ "integrity": "sha512-hzJ3X4vlKT8FQ3Xc4M1szaFVjsc1ZydN+E4VQ91aXxfpjFn9G2wsMo1EFdAXNq/BUnN5dgqIOMP5zRYr3DTsAw==",
+ "dependencies": {
+ "err-code": "^3.0.1",
+ "protobufjs": "^6.10.2"
+ },
+ "engines": {
+ "node": ">=14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/ipfs-unixfs-importer": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-7.0.3.tgz",
+ "integrity": "sha512-qeFOlD3AQtGzr90sr5Tq1Bi8pT5Nr2tSI8z310m7R4JDYgZc6J1PEZO3XZQ8l1kuGoqlAppBZuOYmPEqaHcVQQ==",
+ "dependencies": {
+ "bl": "^5.0.0",
+ "cids": "^1.1.5",
+ "err-code": "^3.0.1",
+ "hamt-sharding": "^2.0.0",
+ "ipfs-unixfs": "^4.0.3",
+ "ipld-dag-pb": "^0.22.2",
+ "it-all": "^1.0.5",
+ "it-batch": "^1.0.8",
+ "it-first": "^1.0.6",
+ "it-parallel-batch": "^1.0.9",
+ "merge-options": "^3.0.4",
+ "multihashing-async": "^2.1.0",
+ "rabin-wasm": "^0.1.4",
+ "uint8arrays": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/it-all": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz",
+ "integrity": "sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A=="
+ },
+ "node_modules/ipfs-only-hash/node_modules/it-batch": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-1.0.9.tgz",
+ "integrity": "sha512-7Q7HXewMhNFltTsAMdSz6luNhyhkhEtGGbYek/8Xb/GiqYMtwUmopE1ocPSiJKKp3rM4Dt045sNFoUu+KZGNyA=="
+ },
+ "node_modules/ipfs-only-hash/node_modules/it-first": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/it-first/-/it-first-1.0.7.tgz",
+ "integrity": "sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g=="
+ },
+ "node_modules/ipfs-only-hash/node_modules/it-parallel-batch": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-1.0.11.tgz",
+ "integrity": "sha512-UWsWHv/kqBpMRmyZJzlmZeoAMA0F3SZr08FBdbhtbe+MtoEBgr/ZUAKrnenhXCBrsopy76QjRH2K/V8kNdupbQ==",
+ "dependencies": {
+ "it-batch": "^1.0.9"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/protobufjs": {
+ "version": "6.11.4",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
+ "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.1",
+ "@types/node": ">=13.7.0",
+ "long": "^4.0.0"
+ },
+ "bin": {
+ "pbjs": "bin/pbjs",
+ "pbts": "bin/pbts"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ipfs-only-hash/node_modules/uint8arrays": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-2.1.10.tgz",
+ "integrity": "sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
+ "node_modules/ipld-dag-pb": {
+ "version": "0.22.3",
+ "resolved": "https://registry.npmjs.org/ipld-dag-pb/-/ipld-dag-pb-0.22.3.tgz",
+ "integrity": "sha512-dfG5C5OVAR4FEP7Al2CrHWvAyIM7UhAQrjnOYOIxXGQz5NlEj6wGX0XQf6Ru6or1na6upvV3NQfstapQG8X2rg==",
+ "deprecated": "This module has been superseded by @ipld/dag-pb and multiformats",
+ "dependencies": {
+ "cids": "^1.0.0",
+ "interface-ipld-format": "^1.0.0",
+ "multicodec": "^3.0.1",
+ "multihashing-async": "^2.0.0",
+ "protobufjs": "^6.10.2",
+ "stable": "^0.1.8",
+ "uint8arrays": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=6.0.0",
+ "npm": ">=3.0.0"
+ }
+ },
+ "node_modules/ipld-dag-pb/node_modules/protobufjs": {
+ "version": "6.11.4",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
+ "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.1",
+ "@types/node": ">=13.7.0",
+ "long": "^4.0.0"
+ },
+ "bin": {
+ "pbjs": "bin/pbjs",
+ "pbts": "bin/pbts"
+ }
+ },
+ "node_modules/ipld-dag-pb/node_modules/uint8arrays": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-2.1.10.tgz",
+ "integrity": "sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
"node_modules/is-array-buffer": {
"version": "3.0.2",
"dev": true,
@@ -7033,7 +7432,6 @@
"version": "2.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -7113,6 +7511,14 @@
"node": ">=8"
}
},
+ "node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-regex": {
"version": "1.1.4",
"dev": true,
@@ -7218,6 +7624,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-wsl": {
"version": "2.2.0",
"dev": true,
@@ -7291,7 +7706,6 @@
"version": "3.0.0",
"dev": true,
"license": "BSD-3-Clause",
- "peer": true,
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
"make-dir": "^3.0.0",
@@ -7305,7 +7719,6 @@
"version": "4.0.1",
"dev": true,
"license": "BSD-3-Clause",
- "peer": true,
"dependencies": {
"debug": "^4.1.1",
"istanbul-lib-coverage": "^3.0.0",
@@ -7319,7 +7732,6 @@
"version": "3.1.5",
"dev": true,
"license": "BSD-3-Clause",
- "peer": true,
"dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
@@ -7339,7 +7751,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/core": "^29.5.0",
"@jest/types": "^29.5.0",
@@ -7365,7 +7776,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"execa": "^5.0.0",
"p-limit": "^3.1.0"
@@ -7378,7 +7788,6 @@
"version": "5.1.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
@@ -7401,7 +7810,6 @@
"version": "2.1.0",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=10.17.0"
}
@@ -7410,7 +7818,6 @@
"version": "2.0.1",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=8"
},
@@ -7422,7 +7829,6 @@
"version": "2.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -7431,7 +7837,6 @@
"version": "4.0.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"path-key": "^3.0.0"
},
@@ -7443,7 +7848,6 @@
"version": "5.1.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
@@ -7458,7 +7862,6 @@
"version": "2.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -7467,7 +7870,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/environment": "^29.5.0",
"@jest/expect": "^29.5.0",
@@ -7498,7 +7900,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/core": "^29.5.0",
"@jest/test-result": "^29.5.0",
@@ -7532,7 +7933,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/core": "^7.11.6",
"@jest/test-sequencer": "^29.5.0",
@@ -7590,7 +7990,6 @@
"version": "29.4.3",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"detect-newline": "^3.0.0"
},
@@ -7602,7 +8001,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/types": "^29.5.0",
"chalk": "^4.0.0",
@@ -7618,7 +8016,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/environment": "^29.5.0",
"@jest/fake-timers": "^29.5.0",
@@ -7665,7 +8062,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"jest-get-type": "^29.4.3",
"pretty-format": "^29.5.0"
@@ -7721,7 +8117,6 @@
"version": "1.2.3",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
},
@@ -7745,7 +8140,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
@@ -7765,7 +8159,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"jest-regex-util": "^29.4.3",
"jest-snapshot": "^29.5.0"
@@ -7778,7 +8171,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/console": "^29.5.0",
"@jest/environment": "^29.5.0",
@@ -7810,7 +8202,6 @@
"version": "0.5.13",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -7820,7 +8211,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/environment": "^29.5.0",
"@jest/fake-timers": "^29.5.0",
@@ -7853,7 +8243,6 @@
"version": "4.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=8"
}
@@ -7909,7 +8298,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/types": "^29.5.0",
"camelcase": "^6.2.0",
@@ -7926,7 +8314,6 @@
"version": "6.3.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=10"
},
@@ -7938,7 +8325,6 @@
"version": "29.5.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jest/test-result": "^29.5.0",
"@jest/types": "^29.5.0",
@@ -7990,6 +8376,11 @@
"@sideway/pinpoint": "^2.0.0"
}
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"license": "MIT"
@@ -8070,11 +8461,18 @@
"json-buffer": "3.0.1"
}
},
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/kleur": {
"version": "3.0.3",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -8083,7 +8481,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
}
@@ -8262,7 +8659,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"semver": "^6.0.0"
},
@@ -8277,7 +8673,6 @@
"version": "6.3.1",
"dev": true,
"license": "ISC",
- "peer": true,
"bin": {
"semver": "bin/semver.js"
}
@@ -8294,6 +8689,17 @@
"tmpl": "1.0.5"
}
},
+ "node_modules/map-obj": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"license": "MIT",
@@ -8312,10 +8718,73 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/meow": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+ "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
+ "dependencies": {
+ "@types/minimist": "^1.2.0",
+ "camelcase-keys": "^6.2.2",
+ "decamelize": "^1.2.0",
+ "decamelize-keys": "^1.1.0",
+ "hard-rejection": "^2.1.0",
+ "minimist-options": "4.1.0",
+ "normalize-package-data": "^3.0.0",
+ "read-pkg-up": "^7.0.1",
+ "redent": "^3.0.0",
+ "trim-newlines": "^3.0.0",
+ "type-fest": "^0.18.0",
+ "yargs-parser": "^20.2.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/meow/node_modules/type-fest": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+ "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/meow/node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/merge-descriptors": {
"version": "1.0.1",
"license": "MIT"
},
+ "node_modules/merge-options": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
+ "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
+ "dependencies": {
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/merge-options/node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"license": "MIT"
@@ -8365,8 +8834,7 @@
},
"node_modules/mime-types": {
"version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@@ -8396,6 +8864,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"license": "ISC",
@@ -8413,6 +8889,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/minimist-options": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+ "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+ "dependencies": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0",
+ "kind-of": "^6.0.3"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/minipass": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
@@ -8485,11 +8974,102 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/multibase": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz",
+ "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "@multiformats/base-x": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=12.0.0",
+ "npm": ">=6.0.0"
+ }
+ },
+ "node_modules/multicodec": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-3.2.1.tgz",
+ "integrity": "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==",
+ "deprecated": "This module has been superseded by the multiformats module",
+ "dependencies": {
+ "uint8arrays": "^3.0.0",
+ "varint": "^6.0.0"
+ }
+ },
+ "node_modules/multicodec/node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
"node_modules/multiformats": {
"version": "9.9.0",
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
},
+ "node_modules/multihashes": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-4.0.3.tgz",
+ "integrity": "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==",
+ "dependencies": {
+ "multibase": "^4.0.1",
+ "uint8arrays": "^3.0.0",
+ "varint": "^5.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0",
+ "npm": ">=6.0.0"
+ }
+ },
+ "node_modules/multihashes/node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
+ "node_modules/multihashes/node_modules/varint": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+ "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+ },
+ "node_modules/multihashing-async": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/multihashing-async/-/multihashing-async-2.1.4.tgz",
+ "integrity": "sha512-sB1MiQXPSBTNRVSJc2zM157PXgDtud2nMFUEIvBrsq5Wv96sUclMRK/ecjoP1T/W61UJBqt4tCTwMkUpt2Gbzg==",
+ "dependencies": {
+ "blakejs": "^1.1.0",
+ "err-code": "^3.0.0",
+ "js-sha3": "^0.8.0",
+ "multihashes": "^4.0.1",
+ "murmurhash3js-revisited": "^3.0.0",
+ "uint8arrays": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0",
+ "npm": ">=6.0.0"
+ }
+ },
+ "node_modules/multihashing-async/node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
+ "node_modules/murmurhash3js-revisited": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz",
+ "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
@@ -8612,6 +9192,20 @@
"version": "2.0.12",
"license": "MIT"
},
+ "node_modules/normalize-package-data": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+ "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+ "dependencies": {
+ "hosted-git-info": "^4.0.1",
+ "is-core-module": "^2.5.0",
+ "semver": "^7.3.4",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"license": "MIT",
@@ -9023,7 +9617,6 @@
"version": "4.2.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"find-up": "^4.0.0"
},
@@ -9035,7 +9628,6 @@
"version": "4.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -9048,7 +9640,6 @@
"version": "5.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"p-locate": "^4.1.0"
},
@@ -9060,7 +9651,6 @@
"version": "2.3.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"p-try": "^2.0.0"
},
@@ -9075,7 +9665,6 @@
"version": "4.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"p-limit": "^2.2.0"
},
@@ -9104,7 +9693,6 @@
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
"dev": true,
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -9156,7 +9744,6 @@
"version": "2.4.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"kleur": "^3.0.3",
"sisteransi": "^1.0.5"
@@ -9216,8 +9803,7 @@
"url": "https://opencollective.com/fast-check"
}
],
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/q": {
"version": "1.5.1",
@@ -9271,6 +9857,64 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/rabin-wasm": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/rabin-wasm/-/rabin-wasm-0.1.5.tgz",
+ "integrity": "sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==",
+ "dependencies": {
+ "@assemblyscript/loader": "^0.9.4",
+ "bl": "^5.0.0",
+ "debug": "^4.3.1",
+ "minimist": "^1.2.5",
+ "node-fetch": "^2.6.1",
+ "readable-stream": "^3.6.0"
+ },
+ "bin": {
+ "rabin-wasm": "cli/bin.js"
+ }
+ },
+ "node_modules/rabin-wasm/node_modules/bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/rabin-wasm/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/rabin-wasm/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -9325,6 +9969,124 @@
"version": "18.2.0",
"license": "MIT"
},
+ "node_modules/read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dependencies": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg/node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+ },
+ "node_modules/read-pkg/node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/read-pkg/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/read-pkg/node_modules/type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/readable-stream": {
"version": "2.3.8",
"license": "MIT",
@@ -9363,6 +10125,18 @@
"node": ">= 0.10"
}
},
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dependencies": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/redis": {
"version": "4.6.7",
"license": "MIT",
@@ -9481,7 +10255,6 @@
"version": "3.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"resolve-from": "^5.0.0"
},
@@ -9493,7 +10266,6 @@
"version": "5.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=8"
}
@@ -9517,7 +10289,6 @@
"version": "2.0.2",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=10"
}
@@ -9928,8 +10699,7 @@
"node_modules/sisteransi": {
"version": "1.0.5",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/slash": {
"version": "3.0.0",
@@ -9967,6 +10737,56 @@
"source-map": "^0.6.0"
}
},
+ "node_modules/sparse-array": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz",
+ "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg=="
+ },
+ "node_modules/spawn-wrap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
+ "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^2.0.0",
+ "is-windows": "^1.0.2",
+ "make-dir": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "signal-exit": "^3.0.2",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+ "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w=="
+ },
"node_modules/split-text-to-chunks": {
"version": "1.0.0",
"dev": true,
@@ -9983,6 +10803,12 @@
"version": "1.0.3",
"license": "BSD-3-Clause"
},
+ "node_modules/stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility"
+ },
"node_modules/stack-utils": {
"version": "2.0.6",
"license": "MIT",
@@ -10032,7 +10858,6 @@
"version": "4.0.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"char-regex": "^1.0.2",
"strip-ansi": "^6.0.0"
@@ -10123,6 +10948,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"dev": true,
@@ -10460,6 +11296,21 @@
"version": "0.0.3",
"license": "MIT"
},
+ "node_modules/trace-unhandled": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/trace-unhandled/-/trace-unhandled-2.0.1.tgz",
+ "integrity": "sha512-wOZbhBiNyuZTs0b/ADZFTiTDVVDsvKQj/RkVJTKefH6u9CowGDSR+H/3miaGUrYCCuzS0nVmIzpbIIm6lRF8gg==",
+ "dev": true,
+ "dependencies": {
+ "haxec": "^2.0.1"
+ },
+ "bin": {
+ "trace-unhandled": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/tree-kill": {
"version": "1.2.2",
"license": "MIT",
@@ -10467,6 +11318,14 @@
"tree-kill": "cli.js"
}
},
+ "node_modules/trim-newlines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/ts-jest": {
"version": "29.1.0",
"dev": true,
@@ -11047,7 +11906,6 @@
"version": "9.1.0",
"dev": true,
"license": "ISC",
- "peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
"@types/istanbul-lib-coverage": "^2.0.1",
@@ -11061,7 +11919,6 @@
"version": "3.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.0.0"
}
@@ -11069,14 +11926,12 @@
"node_modules/v8-to-istanbul/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
@@ -11085,8 +11940,16 @@
"node_modules/v8-to-istanbul/node_modules/convert-source-map": {
"version": "1.9.0",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
},
"node_modules/validator": {
"version": "13.9.0",
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 46b470d1..9855c779 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -4,10 +4,15 @@
"description": "Services to publish content on DSNP/Frequency",
"main": "dist/apps/api/main.js",
"scripts": {
- "build": "npx tsc",
+ "build": "nest build",
"build:swagger": "npx ts-node apps/api/src/generate-metadata.ts",
- "start": "env TS_NODE_BASEURL=./dist/app/api node -r tsconfig-paths/register dist/apps/api/main.js",
- "start:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
+ "format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"",
+ "start": "nest start",
+ "start:api": "nest start api",
+ "start:worker": "nest start worker",
+ "start:api:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
+ "start:worker:dev": "set -a ; . .env.dev ; ts-node-dev -r tsconfig-paths/register apps/worker/src/main.ts",
+ "start:debug": "nest start --debug --watch",
"start:dev:docker": "npm ci && ts-node-dev -r tsconfig-paths/register apps/api/src/main.ts",
"docker-build": "docker build -t content-publishing-service .",
"docker-build:dev": "docker-compose -f docker-compose.dev.yaml build",
@@ -15,7 +20,7 @@
"docker-run:dev": "docker-compose -f docker-compose.dev.yaml up -d ; docker-compose -f docker-compose.dev.yaml logs -f content-publishing-service",
"docker-stop:dev": "docker-compose -f docker-compose.dev.yaml stop",
"clean": "rm -Rf dist",
- "lint": "tsc --noEmit --pretty && eslint \"**/*.ts\" --fix",
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"pretest": "cp env.template .env",
"test": "jest --coverage --verbose",
"test:e2e": "jest --config ./apps/api/test/jest-e2e.json --detectOpenHandles"
@@ -61,9 +66,9 @@
"bullmq": "^3.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
- "crypto": "^1.0.1",
"form-data": "^4.0.0",
"ioredis": "^5.3.2",
+ "ipfs-only-hash": "^4.0.0",
"joi": "^17.9.1",
"mime-types": "^2.1.35",
"multiformats": "^9.9.0",
@@ -90,8 +95,12 @@
"eslint-plugin-nestjs": "^1.2.3",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
+ "jest": "^29.5.0",
"license-report": "^6.4.0",
+ "prettier": "^3.0.2",
+ "source-map-support": "^0.5.21",
"supertest": "^6.3.3",
+ "trace-unhandled": "^2.0.1",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
diff --git a/services/content-watcher/tsconfig.build.json b/services/content-watcher/tsconfig.build.json
new file mode 100644
index 00000000..c460c168
--- /dev/null
+++ b/services/content-watcher/tsconfig.build.json
@@ -0,0 +1,7 @@
+{
+ "extends": "./tsconfig.json",
+ "include": [
+ "./**/*.ts"
+ ],
+ "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
+}
diff --git a/services/content-watcher/tsconfig.json b/services/content-watcher/tsconfig.json
index 4f5f22b5..8b70d256 100644
--- a/services/content-watcher/tsconfig.json
+++ b/services/content-watcher/tsconfig.json
@@ -1,6 +1,4 @@
{
- "$schema": "https://json.schemastore.org/tsconfig",
- "display": "Base",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": "./src",
@@ -28,17 +26,9 @@
"strict": true,
"skipLibCheck": true,
"strictPropertyInitialization": false,
- "target": "es2022",
+ "target": "es2021",
"typeRoots": [
"node_modules/@types"
]
- },
- "include": [
- "./**/*.ts"
- ],
- "exclude": [
- "node_modules/**",
- "./dist/**",
- "/tools/**"
- ]
+ }
}
\ No newline at end of file
From 682ab722b3ba3f5d98885fc36f169567d9445736 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 6 Sep 2023 18:13:58 -0500
Subject: [PATCH 013/137] IPFS announcer: announces batches on ipfs as parquet
file (#28)
* add announcements to payload
* park some work
* add parquet placeholders
* some placeholders
* add more logic for IPFS announcement
* cleanup
* add depdencies
* remove helia
* setup helia
* breaking
* comment our multiformats for now
* set pinning note for announcer
* cleanup
* cleanup: todo, multiformats issue
* use multiformats 0.9.9
* placeholders
* set more placeholders
* base 32
* cleanup
* fill in the blanks
* adda test
* cleanup batchAnnouncer/extract dnspConverter
* revert
* cleanup
* cleanup
* address feedback
* cleanupand fix tests
* revert
* use cache for schemas
* rename
---
.../api/src/config/config.service.spec.ts | 4 +
.../apps/api/src/config/env.config.ts | 4 +
.../batch_announcer/batch.announcer.module.ts | 9 +-
.../batch.announcer.service.ts | 10 +-
.../batch_announcer/batch.announcer.spec.ts | 88 +++++++++
.../src/batch_announcer/batch.announcer.ts | 89 +++++++++
.../batch_announcer/ipfs.announcer.spec.ts | 13 --
.../src/batch_announcer/ipfs.announcer.ts | 16 --
.../src/blockchain/blockchain.service.ts | 9 +-
.../batch-announcer.job.interface.ts | 3 +
services/content-watcher/env.template | 4 +
.../libs/common/src/interfaces/dsnp.ts | 183 ++++++++++++++++++
.../common/src/utils/dsnpTypeConverter.ts | 176 +++++++++++++++++
.../libs/common/src/utils/ipfs.client.ts | 2 +-
services/content-watcher/package-lock.json | 142 ++++++++++++--
services/content-watcher/package.json | 5 +-
16 files changed, 700 insertions(+), 57 deletions(-)
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
create mode 100644 services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
delete mode 100644 services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
delete mode 100644 services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
create mode 100644 services/content-watcher/libs/common/src/interfaces/dsnp.ts
create mode 100644 services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
diff --git a/services/content-watcher/apps/api/src/config/config.service.spec.ts b/services/content-watcher/apps/api/src/config/config.service.spec.ts
index 52bdd194..549c54c9 100644
--- a/services/content-watcher/apps/api/src/config/config.service.spec.ts
+++ b/services/content-watcher/apps/api/src/config/config.service.spec.ts
@@ -38,6 +38,10 @@ describe('ContentPublishingConfigService', () => {
const ALL_ENV: { [key: string]: string | undefined } = {
REDIS_URL: undefined,
FREQUENCY_URL: undefined,
+ IPFS_ENDPOINT: undefined,
+ IPFS_GATEWAY_URL: undefined,
+ IPFS_BASIC_AUTH_USER: undefined,
+ IPFS_BASIC_AUTH_SECRET: undefined,
PROVIDER_ID: undefined,
BLOCKCHAIN_SCAN_INTERVAL_MINUTES: undefined,
QUEUE_HIGH_WATER: undefined,
diff --git a/services/content-watcher/apps/api/src/config/env.config.ts b/services/content-watcher/apps/api/src/config/env.config.ts
index 8e83ddf8..a6bd6411 100644
--- a/services/content-watcher/apps/api/src/config/env.config.ts
+++ b/services/content-watcher/apps/api/src/config/env.config.ts
@@ -5,6 +5,10 @@ import { mnemonicValidate } from '@polkadot/util-crypto';
export const configModuleOptions: ConfigModuleOptions = {
isGlobal: true,
validationSchema: Joi.object({
+ IPFS_ENDPOINT: Joi.string().uri().required(),
+ IPFS_GATEWAY_URL: Joi.string().required(), // This is parse as string as the required format of this not a valid uri, check .env.template
+ IPFS_BASIC_AUTH_USER: Joi.string().allow('').default(''),
+ IPFS_BASIC_AUTH_SECRET: Joi.string().allow('').default(''),
REDIS_URL: Joi.string().uri().required(),
FREQUENCY_URL: Joi.string().uri().required(),
PROVIDER_ID: Joi.required().custom((value: string, helpers) => {
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
index 206e1284..6c2c1f84 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.module.ts
@@ -9,12 +9,15 @@ import { RedisModule } from '@liaoliaots/nestjs-redis';
import { BatchAnnouncementService } from './batch.announcer.service';
import { ConfigModule } from '../../../api/src/config/config.module';
import { ConfigService } from '../../../api/src/config/config.service';
-import { IPFSAnnouncer } from './ipfs.announcer';
+import { BatchAnnouncer } from './batch.announcer';
import { QueueConstants } from '../../../../libs/common/src';
+import { BlockchainModule } from '../blockchain/blockchain.module';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
@Module({
imports: [
ConfigModule,
+ BlockchainModule,
EventEmitterModule,
RedisModule.forRootAsync(
{
@@ -75,7 +78,7 @@ import { QueueConstants } from '../../../../libs/common/src';
),
],
controllers: [],
- providers: [BatchAnnouncementService, IPFSAnnouncer],
- exports: [BullModule, BatchAnnouncementService, IPFSAnnouncer],
+ providers: [BatchAnnouncementService, BatchAnnouncer, IpfsService],
+ exports: [BullModule, BatchAnnouncementService, BatchAnnouncer, IpfsService],
})
export class BatchAnnouncerModule {}
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
index 9a9ce51b..0bb623d2 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.service.ts
@@ -6,7 +6,7 @@ import Redis from 'ioredis';
import { SchedulerRegistry } from '@nestjs/schedule';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { ConfigService } from '../../../api/src/config/config.service';
-import { IPFSAnnouncer } from './ipfs.announcer';
+import { BatchAnnouncer } from './batch.announcer';
import { CAPACITY_EPOCH_TIMEOUT_NAME } from '../../../../libs/common/src/constants';
import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
import { QueueConstants } from '../../../../libs/common/src';
@@ -18,13 +18,11 @@ import { QueueConstants } from '../../../../libs/common/src';
export class BatchAnnouncementService extends WorkerHost implements OnApplicationBootstrap, OnModuleDestroy {
private logger: Logger;
- private capacityExhausted = false;
-
constructor(
@InjectRedis() private cacheManager: Redis,
@InjectQueue(QueueConstants.PUBLISH_QUEUE_NAME) private publishQueue: Queue,
private configService: ConfigService,
- private ipfsPublisher: IPFSAnnouncer,
+ private ipfsPublisher: BatchAnnouncer,
private schedulerRegistry: SchedulerRegistry,
private eventEmitter: EventEmitter2,
) {
@@ -47,7 +45,9 @@ export class BatchAnnouncementService extends WorkerHost implements OnApplicatio
async process(job: Job): Promise {
this.logger.log(`Processing job ${job.id} of type ${job.name}`);
try {
- await this.ipfsPublisher.announce(job.data);
+ const publisherJob = await this.ipfsPublisher.announce(job.data);
+
+ await this.publishQueue.add(publisherJob.id, publisherJob);
this.logger.log(`Completed job ${job.id} of type ${job.name}`);
return job.data;
} catch (e) {
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
new file mode 100644
index 00000000..52ffefdc
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
@@ -0,0 +1,88 @@
+import { expect, describe, jest, it, beforeEach } from '@jest/globals';
+import assert from 'assert';
+import { FrequencyParquetSchema } from '@dsnp/frequency-schemas/types/frequency';
+import Redis from 'ioredis-mock';
+import { BatchAnnouncer } from './batch.announcer';
+
+// Create a mock for the dependencies
+const mockConfigService = {
+ getIpfsCidPlaceholder: jest.fn(),
+};
+
+const mockBlockchainService = {
+ getSchema: jest.fn(),
+};
+
+const mockIpfsService = {
+ getPinned: jest.fn(),
+ ipfsPin: jest.fn(),
+};
+
+describe('BatchAnnouncer', () => {
+ let ipfsAnnouncer: BatchAnnouncer;
+
+ const broadcast: FrequencyParquetSchema = [
+ {
+ name: 'announcementType',
+ column_type: {
+ INTEGER: {
+ bit_width: 32,
+ sign: true,
+ },
+ },
+ compression: 'GZIP',
+ bloom_filter: false,
+ },
+ {
+ name: 'contentHash',
+ column_type: 'BYTE_ARRAY',
+ compression: 'GZIP',
+ bloom_filter: true,
+ },
+ {
+ name: 'fromId',
+ column_type: {
+ INTEGER: {
+ bit_width: 64,
+ sign: false,
+ },
+ },
+ compression: 'GZIP',
+ bloom_filter: true,
+ },
+ {
+ name: 'url',
+ column_type: 'STRING',
+ compression: 'GZIP',
+ bloom_filter: false,
+ },
+ ];
+ const mockClient = new Redis();
+
+ beforeEach(async () => {
+ ipfsAnnouncer = new BatchAnnouncer(mockClient, mockConfigService as any, mockBlockchainService as any, mockIpfsService as any);
+ });
+ it('should be defined', () => {
+ expect(ipfsAnnouncer).toBeDefined();
+ });
+
+ // Write your test cases here
+ it('should announce a batch to IPFS', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockBlockchainService.getSchema.mockReturnValue({ model: JSON.stringify(broadcast) });
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', size: 'mockSize' });
+
+ const batchJob = {
+ batchId: 'mockBatchId',
+ schemaId: 123,
+ announcements: [],
+ };
+
+ const result = await ipfsAnnouncer.announce(batchJob);
+ assert(result);
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockBlockchainService.getSchema).toHaveBeenCalledWith(123);
+ });
+});
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
new file mode 100644
index 00000000..1f39cedf
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
@@ -0,0 +1,89 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { PassThrough } from 'node:stream';
+import { ParquetWriter } from '@dsnp/parquetjs';
+import { fromFrequencySchema } from '@dsnp/frequency-schemas/parquet';
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import Redis from 'ioredis';
+import { PalletSchemasSchema } from '@polkadot/types/lookup';
+import { BlockchainService } from '../blockchain/blockchain.service';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
+import { IPublisherJob } from '../interfaces/publisher-job.interface';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+@Injectable()
+export class BatchAnnouncer {
+ private logger: Logger;
+
+ constructor(
+ @InjectRedis() private cacheManager: Redis,
+ private configService: ConfigService,
+ private blockchainService: BlockchainService,
+ private ipfsService: IpfsService,
+ ) {
+ this.logger = new Logger(BatchAnnouncer.name);
+ }
+
+ public async announce(batchJob: IBatchAnnouncerJobData): Promise {
+ this.logger.debug(`Announcing batch ${batchJob.batchId} on IPFS`);
+ const { batchId, schemaId, announcements } = batchJob;
+
+ let frequencySchema: PalletSchemasSchema;
+
+ const schemaCacheKey = `schema:${schemaId}`;
+ const cachedSchema = await this.cacheManager.get(schemaCacheKey);
+ if (cachedSchema) {
+ frequencySchema = JSON.parse(cachedSchema);
+ } else {
+ frequencySchema = await this.blockchainService.getSchema(schemaId);
+ await this.cacheManager.set(schemaCacheKey, JSON.stringify(frequencySchema));
+ }
+
+ const schema = JSON.parse(frequencySchema.model.toString());
+ if (!schema) {
+ throw new Error(`Unable to parse schema for schemaId ${schemaId}`);
+ }
+
+ const [parquetSchema, writerOptions] = fromFrequencySchema(schema);
+ const publishStream = new PassThrough();
+
+ const writer = await ParquetWriter.openStream(parquetSchema, publishStream as any, writerOptions);
+
+ announcements.forEach(async (announcement) => {
+ writer.appendRow(announcement);
+ });
+
+ await writer.close();
+ const buffer = await this.bufferPublishStream(publishStream);
+ const [cid, hash] = await this.pinStringToIPFS(buffer);
+ const ipfsUrl = await this.formIpfsUrl(cid);
+ this.logger.debug(`Batch ${batchId} published to IPFS at ${ipfsUrl}`);
+ this.logger.debug(`Batch ${batchId} hash: ${hash}`);
+ return { id: batchId, schemaId, data: { cid, payloadLength: buffer.length } };
+ }
+
+ private async bufferPublishStream(publishStream: PassThrough): Promise {
+ this.logger.debug('Buffering publish stream');
+ return new Promise((resolve, reject) => {
+ const buffers: Buffer[] = [];
+ publishStream.on('data', (data) => {
+ buffers.push(data);
+ });
+ publishStream.on('end', () => {
+ resolve(Buffer.concat(buffers));
+ });
+ publishStream.on('error', (err) => {
+ reject(err);
+ });
+ });
+ }
+
+ private async pinStringToIPFS(buf: Buffer): Promise<[string, string]> {
+ const { cid, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
+ return [cid.toString(), size.toString()];
+ }
+
+ private async formIpfsUrl(cid: string): Promise {
+ return this.configService.getIpfsCidPlaceholder(cid);
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
deleted file mode 100644
index fafa3c61..00000000
--- a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// test file for ipfs announcer
-import { describe, it, beforeEach } from '@jest/globals';
-import { IPFSAnnouncer } from './ipfs.announcer';
-
-describe('IPFSAnnouncer', () => {
- let ipfsAnnouncer: IPFSAnnouncer;
-
- beforeEach(async () => {});
-
- describe('announce', () => {
- it('should announce a batch on ipfs', async () => {});
- });
-});
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts b/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
deleted file mode 100644
index f548271e..00000000
--- a/services/content-watcher/apps/worker/src/batch_announcer/ipfs.announcer.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Injectable, Logger } from '@nestjs/common';
-import { ConfigService } from '../../../api/src/config/config.service';
-import { IBatchAnnouncerJobData } from '../interfaces/batch-announcer.job.interface';
-
-@Injectable()
-export class IPFSAnnouncer {
- private logger: Logger;
-
- constructor(private configService: ConfigService) {
- this.logger = new Logger(IPFSAnnouncer.name);
- }
-
- public async announce(batchJob: IBatchAnnouncerJobData): Promise {
- this.logger.log(`Announcing batch ${batchJob.batchId} on IPFS`);
- }
-}
diff --git a/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
index 3cdd832d..00b303d2 100644
--- a/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
+++ b/services/content-watcher/apps/worker/src/blockchain/blockchain.service.ts
@@ -7,8 +7,8 @@ import { KeyringPair } from '@polkadot/keyring/types';
import { BlockHash, BlockNumber } from '@polkadot/types/interfaces';
import { SubmittableExtrinsic } from '@polkadot/api/types';
import { AnyNumber, ISubmittableResult } from '@polkadot/types/types';
-import { u32, Option, u128 } from '@polkadot/types';
-import { PalletCapacityCapacityDetails, PalletCapacityEpochInfo } from '@polkadot/types/lookup';
+import { u32, Option } from '@polkadot/types';
+import { PalletCapacityCapacityDetails, PalletCapacityEpochInfo, PalletSchemasSchema } from '@polkadot/types/lookup';
import { ConfigService } from '../../../api/src/config/config.service';
import { Extrinsic } from './extrinsic';
@@ -139,4 +139,9 @@ export class BlockchainService implements OnApplicationBootstrap, OnApplicationS
public async capacityBatchLimit(): Promise {
return this.api.consts.frequencyTxPayment.maximumCapacityBatchLength.toNumber();
}
+
+ public async getSchema(schemaId: number): Promise {
+ const schema: PalletSchemasSchema = await this.query('schemas', 'schemas', schemaId);
+ return schema;
+ }
}
diff --git a/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts b/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
index 25d5bbf9..10cb3b07 100644
--- a/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
+++ b/services/content-watcher/apps/worker/src/interfaces/batch-announcer.job.interface.ts
@@ -1,4 +1,7 @@
+import { Announcement } from '../../../../libs/common/src/interfaces/dsnp';
+
export interface IBatchAnnouncerJobData {
batchId: string;
schemaId: number;
+ announcements: Announcement[];
}
diff --git a/services/content-watcher/env.template b/services/content-watcher/env.template
index 8afa0581..bc6fd8a1 100644
--- a/services/content-watcher/env.template
+++ b/services/content-watcher/env.template
@@ -1,4 +1,8 @@
# Copy this file to ".env.dev" and ".env.docker.dev", and then tweak values for local development
+IPFS_ENDPOINT="https://ipfs.infura.io:5001"
+IPFS_BASIC_AUTH_USER="Infura Project ID Here or Blank for Kubo RPC"
+IPFS_BASIC_AUTH_SECRET="Infura Secret Here or Blank for Kubo RPC"
+IPFS_GATEWAY_URL="https://ipfs.io/ipfs/[CID]"
FREQUENCY_URL=ws://0.0.0.0:9944
PROVIDER_ID=1
REDIS_URL=redis://0.0.0.0:6379
diff --git a/services/content-watcher/libs/common/src/interfaces/dsnp.ts b/services/content-watcher/libs/common/src/interfaces/dsnp.ts
new file mode 100644
index 00000000..5b0170d8
--- /dev/null
+++ b/services/content-watcher/libs/common/src/interfaces/dsnp.ts
@@ -0,0 +1,183 @@
+/**
+ * AnnouncementType: an enum representing different types of DSNP announcements
+ */
+
+import { ActivityContentNote } from '@dsnp/activity-content/types';
+
+// eslint-disable-next-line no-shadow
+export enum AnnouncementType {
+ Tombstone = 0,
+ Broadcast = 2,
+ Reply = 3,
+ Reaction = 4,
+ Profile = 5,
+ Update = 6,
+ PublicFollows = 113,
+}
+
+type TombstoneFields = {
+ announcementType: AnnouncementType.Tombstone;
+ targetAnnouncementType: AnnouncementType;
+ targetSignature: string;
+};
+
+type BroadcastFields = {
+ announcementType: AnnouncementType.Broadcast;
+ contentHash: string;
+ url: string;
+};
+
+type ReplyFields = {
+ announcementType: AnnouncementType.Reply;
+ contentHash: string;
+ inReplyTo: string;
+ url: string;
+};
+
+type ReactionFields = {
+ announcementType: AnnouncementType.Reaction;
+ emoji: string;
+ inReplyTo: string;
+};
+
+type ProfileFields = {
+ announcementType: AnnouncementType.Profile;
+ contentHash: string;
+ url: string;
+};
+
+/**
+ * TypedAnnouncement: an Announcement with a particular AnnouncementType
+ */
+export type TypedAnnouncement = {
+ announcementType: T;
+ fromId: string;
+} & (TombstoneFields | BroadcastFields | ReplyFields | ReactionFields | ProfileFields);
+
+/**
+ * Announcement: an Announcement intended for inclusion in a batch file
+ */
+export type Announcement = TypedAnnouncement;
+
+/**
+ * ProfileAnnouncement: an Announcement of type Profile
+ */
+export type ProfileAnnouncement = TypedAnnouncement;
+
+/**
+ * TombstoneAnnouncement: an Announcement of type Tombstone
+ */
+export type TombstoneAnnouncement = TypedAnnouncement;
+
+/**
+ * BroadcastAnnouncement: an Announcement of type Broadcast
+ */
+export type BroadcastAnnouncement = TypedAnnouncement;
+
+/**
+ * ReplyAnnouncement: am announcement of type Reply
+ */
+export type ReplyAnnouncement = TypedAnnouncement;
+
+/**
+ * ReactionAnnouncement: an Announcement of type Reaction
+ */
+export type ReactionAnnouncement = TypedAnnouncement;
+
+/**
+ * createTombstone() generates a tombstone announcement from a given URL and
+ * hash.
+ *
+ * @param fromId - The id of the user from whom the announcement is posted
+ * @param targetType - The DSNP announcement type of the target announcement
+ * @param targetSignature - The signature of the target announcement
+ * @returns A TombstoneAnnouncement
+ */
+export const createTombstone = (fromId: string, targetType: AnnouncementType, targetSignature: string): TombstoneAnnouncement => ({
+ announcementType: AnnouncementType.Tombstone,
+ targetAnnouncementType: targetType,
+ targetSignature,
+ fromId,
+});
+
+/**
+ * createBroadcast() generates a broadcast announcement from a given URL and
+ * hash.
+ *
+ * @param fromId - The id of the user from whom the announcement is posted
+ * @param url - The URL of the activity content to reference
+ * @param hash - The hash of the content at the URL
+ * @returns A BroadcastAnnouncement
+ */
+export const createBroadcast = (fromId: string, url: string, hash: string): BroadcastAnnouncement => ({
+ announcementType: AnnouncementType.Broadcast,
+ contentHash: hash,
+ fromId,
+ url,
+});
+
+/**
+ * createReply() generates a reply announcement from a given URL, hash and
+ * content uri.
+ *
+ * @param fromId - The id of the user from whom the announcement is posted
+ * @param url - The URL of the activity content to reference
+ * @param hash - The hash of the content at the URL
+ * @param inReplyTo - The DSNP Content Uri of the parent announcement
+ * @returns A ReplyAnnouncement
+ */
+export const createReply = (fromId: string, url: string, hash: string, inReplyTo: string): ReplyAnnouncement => ({
+ announcementType: AnnouncementType.Reply,
+ contentHash: hash,
+ fromId,
+ inReplyTo,
+ url,
+});
+
+/**
+ * createReaction() generates a reaction announcement from a given URL, hash and
+ * content uri.
+ *
+ * @param fromId - The id of the user from whom the announcement is posted
+ * @param emoji - The emoji to respond with
+ * @param inReplyTo - The DSNP Content Uri of the parent announcement
+ * @returns A ReactionAnnouncement
+ */
+export const createReaction = (fromId: string, emoji: string, inReplyTo: string): ReactionAnnouncement => ({
+ announcementType: AnnouncementType.Reaction,
+ emoji,
+ fromId,
+ inReplyTo,
+});
+
+/**
+ * createProfile() generates a profile announcement from a given URL and hash.
+ *
+ * @param fromId - The id of the user from whom the announcement is posted
+ * @param url - The URL of the activity content to reference
+ * @param hash - The hash of the content at the URL
+ * @returns A ProfileAnnouncement
+ */
+export const createProfile = (fromId: string, url: string, hash: string): ProfileAnnouncement => ({
+ announcementType: AnnouncementType.Profile,
+ contentHash: hash,
+ fromId,
+ url,
+});
+
+/**
+ * createNote() provides a simple factory for generating an ActivityContentNote
+ * object.
+ * @param content - The text content to include in the note
+ * @param published - the Date that the note was claimed to be published
+ * @param options - Overrides default fields for the ActivityContentNote
+ * @returns An ActivityContentNote object
+ */
+export const createNote = (content: string, published: Date, options?: Partial): ActivityContentNote => ({
+ '@context': 'https://www.w3.org/ns/activitystreams',
+ type: 'Note',
+ mediaType: 'text/plain',
+ published: published.toISOString(),
+ content,
+ ...options,
+});
diff --git a/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts b/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
new file mode 100644
index 00000000..014c70dd
--- /dev/null
+++ b/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
@@ -0,0 +1,176 @@
+import { Injectable, Logger } from '@nestjs/common';
+import {
+ ActivityContentTag,
+ ActivityContentAttachment,
+ ActivityContentLink,
+ ActivityContentImageLink,
+ ActivityContentImage,
+ ActivityContentVideoLink,
+ ActivityContentVideo,
+ ActivityContentAudioLink,
+ ActivityContentAudio,
+} from '@dsnp/activity-content/types';
+import { TagTypeDto, AssetDto, AttachmentTypeDto } from '../dtos/activity.dto';
+import { createNote } from '../interfaces/dsnp';
+import { calculateDsnpHash } from './ipfs';
+import { IpfsService } from './ipfs.client';
+import { ConfigService } from '../../../../apps/api/src/config/config.service';
+
+@Injectable()
+export class BatchAnnouncer {
+ private logger: Logger;
+
+ constructor(
+ private configService: ConfigService,
+ private ipfsService: IpfsService,
+ ) {
+ this.logger = new Logger(BatchAnnouncer.name);
+ }
+
+ public async prepareNote(noteContent?: any): Promise<[string, string, string]> {
+ this.logger.debug(`Preparing note`);
+ const tags: ActivityContentTag[] = [];
+ if (noteContent?.content.tag) {
+ noteContent.content.tag.forEach((tag) => {
+ switch (tag.type) {
+ case TagTypeDto.Hashtag:
+ tags.push({ name: tag.name || '' });
+ break;
+ case TagTypeDto.Mention:
+ tags.push({
+ name: tag.name || '',
+ type: 'Mention',
+ id: tag.mentionedId || '',
+ });
+ break;
+ default:
+ throw new Error(`Unsupported tag type ${typeof tag.type}`);
+ }
+ });
+ }
+
+ const attachments: ActivityContentAttachment[] = [];
+ if (noteContent?.content.assets) {
+ noteContent.content.assets.forEach(async (asset: AssetDto) => {
+ switch (asset.type) {
+ case AttachmentTypeDto.LINK: {
+ const link: ActivityContentLink = {
+ type: 'Link',
+ href: asset.href || '',
+ name: asset.name || '',
+ };
+
+ attachments.push(link);
+ break;
+ }
+ case AttachmentTypeDto.IMAGE: {
+ const imageLinks: ActivityContentImageLink[] = [];
+ asset.references?.forEach(async (reference) => {
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ const image: ActivityContentImageLink = {
+ mediaType: 'image', // TODO
+ hash: [hashedContent],
+ height: reference.height,
+ width: reference.width,
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ imageLinks.push(image);
+ });
+ const imageActivity: ActivityContentImage = {
+ type: 'Image',
+ name: asset.name || '',
+ url: imageLinks,
+ };
+
+ attachments.push(imageActivity);
+ break;
+ }
+ case AttachmentTypeDto.VIDEO: {
+ const videoLinks: ActivityContentVideoLink[] = [];
+ let duration = '';
+ asset.references?.forEach(async (reference) => {
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ const video: ActivityContentVideoLink = {
+ mediaType: 'video', // TODO
+ hash: [hashedContent],
+ height: reference.height,
+ width: reference.width,
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ duration = reference.duration ?? '';
+ videoLinks.push(video);
+ });
+ const videoActivity: ActivityContentVideo = {
+ type: 'Video',
+ name: asset.name || '',
+ url: videoLinks,
+ duration,
+ };
+
+ attachments.push(videoActivity);
+ break;
+ }
+ case AttachmentTypeDto.AUDIO: {
+ const audioLinks: ActivityContentAudioLink[] = [];
+ let duration = '';
+ asset.references?.forEach(async (reference) => {
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ duration = reference.duration ?? '';
+ const audio: ActivityContentAudioLink = {
+ mediaType: 'audio', // TODO
+ hash: [hashedContent],
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ audioLinks.push(audio);
+ });
+ const audioActivity: ActivityContentAudio = {
+ type: 'Audio',
+ name: asset.name || '',
+ url: audioLinks,
+ duration,
+ };
+
+ attachments.push(audioActivity);
+ break;
+ }
+ default:
+ throw new Error(`Unsupported attachment type ${typeof asset.type}`);
+ }
+ });
+ }
+
+ const note = createNote(noteContent?.content.content ?? '', new Date(noteContent?.content.published ?? ''), {
+ name: noteContent?.content.name,
+ location: {
+ latitude: noteContent?.content.location?.latitude,
+ longitude: noteContent?.content.location?.longitude,
+ radius: noteContent?.content.location?.radius,
+ altitude: noteContent?.content.location?.altitude,
+ accuracy: noteContent?.content.location?.accuracy,
+ name: noteContent?.content.location?.name || '',
+ type: 'Place',
+ },
+ tag: tags,
+ attachment: attachments,
+ });
+ const noteString = JSON.stringify(note);
+ const [cid, hash] = await this.pinStringToIPFS(Buffer.from(noteString));
+ const ipfsUrl = await this.formIpfsUrl(cid);
+ return [cid, hash, ipfsUrl];
+ }
+
+ private async pinStringToIPFS(buf: Buffer): Promise<[string, string]> {
+ const { cid, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
+ return [cid.toString(), size.toString()];
+ }
+
+ private async formIpfsUrl(cid: string): Promise {
+ return this.configService.getIpfsCidPlaceholder(cid);
+ }
+}
diff --git a/services/content-watcher/libs/common/src/utils/ipfs.client.ts b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
index 0729d642..7cc9c320 100644
--- a/services/content-watcher/libs/common/src/utils/ipfs.client.ts
+++ b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
@@ -6,9 +6,9 @@ import FormData from 'form-data';
import { extension as getExtension } from 'mime-types';
import { CID } from 'multiformats/cid';
import { blake2b256 as hasher } from '@multiformats/blake2/blake2b';
-import { base58btc } from 'multiformats/bases/base58';
import { create } from 'multiformats/hashes/digest';
import { randomUUID } from 'crypto';
+import { base58btc } from 'multiformats/bases/base58';
import { ConfigService } from '../../../../apps/api/src/config/config.service';
export interface FilePin {
diff --git a/services/content-watcher/package-lock.json b/services/content-watcher/package-lock.json
index db2c7091..67a5f2f3 100644
--- a/services/content-watcher/package-lock.json
+++ b/services/content-watcher/package-lock.json
@@ -9,6 +9,8 @@
"version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
+ "@dsnp/activity-content": "^1.1.0",
+ "@dsnp/frequency-schemas": "^1.0.2",
"@dsnp/parquetjs": "^1.3.4",
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
@@ -43,7 +45,7 @@
"ipfs-only-hash": "^4.0.0",
"joi": "^17.9.1",
"mime-types": "^2.1.35",
- "multiformats": "^9.9.0",
+ "multiformats": "9.9.0",
"rxjs": "^7.8.1",
"time-constants": "^1.0.3"
},
@@ -67,6 +69,7 @@
"eslint-plugin-nestjs": "^1.2.3",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
+ "ioredis-mock": "^8.8.3",
"jest": "^29.5.0",
"license-report": "^6.4.0",
"prettier": "^3.0.2",
@@ -764,7 +767,6 @@
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
@@ -773,6 +775,49 @@
"node": ">=12"
}
},
+ "node_modules/@dsnp/activity-content": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@dsnp/activity-content/-/activity-content-1.1.0.tgz",
+ "integrity": "sha512-T83Bi3Nn4uUOySAECaUuNZ+1XkL1c3VENAxKv1m9n76J0GApeLcRfujtWZnPNJGZJp+wgLbmjoTBxulwjbDW4w==",
+ "dependencies": {
+ "@multiformats/blake2": "^1.0.13",
+ "multiformats": "^11.0.2"
+ }
+ },
+ "node_modules/@dsnp/activity-content/node_modules/multiformats": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-11.0.2.tgz",
+ "integrity": "sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg==",
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@dsnp/frequency-schemas": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@dsnp/frequency-schemas/-/frequency-schemas-1.0.2.tgz",
+ "integrity": "sha512-+u2Fwv9aYbMn7MI5LbiDn92dWK+YxcJJEwdy6r/wdQwFVz/jZtE5lR56KqPYS2piun/vINMJU+HNZUVYL4zkOg==",
+ "dependencies": {
+ "@frequency-chain/api-augment": "0.0.0-45e306",
+ "@polkadot/api": "^10.7.3",
+ "json-stringify-pretty-compact": "^4.0.0",
+ "ts-node": "^10.9.1",
+ "typescript": "^5.0.4"
+ },
+ "optionalDependencies": {
+ "@dsnp/parquetjs": "^1.3.0"
+ }
+ },
+ "node_modules/@dsnp/frequency-schemas/node_modules/@frequency-chain/api-augment": {
+ "version": "0.0.0-45e306",
+ "resolved": "https://registry.npmjs.org/@frequency-chain/api-augment/-/api-augment-0.0.0-45e306.tgz",
+ "integrity": "sha512-VzZIFwMX8LaY6dJfzsJ6t9WKZ28DzGA4+lEKys0OR6O+CIAV/fVWNb8FaHG9c6It0GmSz2Os0ehvn5p/rgWfug==",
+ "dependencies": {
+ "@polkadot/api": "^10.7.3",
+ "@polkadot/rpc-provider": "^10.7.3",
+ "@polkadot/types": "^10.7.3"
+ }
+ },
"node_modules/@dsnp/parquetjs": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/@dsnp/parquetjs/-/parquetjs-1.3.4.tgz",
@@ -898,6 +943,12 @@
"dev": true,
"license": "BSD-3-Clause"
},
+ "node_modules/@ioredis/as-callback": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@ioredis/as-callback/-/as-callback-3.0.0.tgz",
+ "integrity": "sha512-Kqv1rZ3WbgOrS+hgzJ5xG5WQuhvzzSTRYvNeyPMLOAM78MHSnuKI20JeJGbpuAt//LCuP0vsexZcorqW7kWhJg==",
+ "dev": true
+ },
"node_modules/@ioredis/commands": {
"version": "1.2.0",
"license": "MIT"
@@ -2684,22 +2735,18 @@
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@types/babel__core": {
@@ -2830,6 +2877,16 @@
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ=="
},
+ "node_modules/@types/ioredis-mock": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/@types/ioredis-mock/-/ioredis-mock-8.2.2.tgz",
+ "integrity": "sha512-bnbPHOjxy4TUDjRh61MMoK2QvDNZqrMDXJYrEDZP/HPFvBubR24CQ0DBi5lgWhLxG4lvVsXPRDXtZ03+JgonoQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "ioredis": ">=5"
+ }
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
"license": "MIT"
@@ -3619,7 +3676,6 @@
},
"node_modules/acorn-walk": {
"version": "8.2.0",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.4.0"
@@ -3764,7 +3820,6 @@
},
"node_modules/arg": {
"version": "4.1.3",
- "devOptional": true,
"license": "MIT"
},
"node_modules/argparse": {
@@ -4877,7 +4932,6 @@
},
"node_modules/create-require": {
"version": "1.1.1",
- "devOptional": true,
"license": "MIT"
},
"node_modules/cron": {
@@ -5180,7 +5234,6 @@
},
"node_modules/diff": {
"version": "4.0.2",
- "devOptional": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
@@ -6197,6 +6250,32 @@
"bser": "2.1.1"
}
},
+ "node_modules/fengari": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz",
+ "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==",
+ "dev": true,
+ "dependencies": {
+ "readline-sync": "^1.4.9",
+ "sprintf-js": "^1.1.1",
+ "tmp": "^0.0.33"
+ }
+ },
+ "node_modules/fengari-interop": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/fengari-interop/-/fengari-interop-0.1.3.tgz",
+ "integrity": "sha512-EtZ+oTu3kEwVJnoymFPBVLIbQcCoy9uWCVnMA6h3M/RqHkUBsLYp29+RRHf9rKr6GwjubWREU1O7RretFIXjHw==",
+ "dev": true,
+ "peerDependencies": {
+ "fengari": "^0.1.0"
+ }
+ },
+ "node_modules/fengari/node_modules/sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ },
"node_modules/fetch-blob": {
"version": "3.2.0",
"funding": [
@@ -7103,6 +7182,26 @@
"url": "https://opencollective.com/ioredis"
}
},
+ "node_modules/ioredis-mock": {
+ "version": "8.8.3",
+ "resolved": "https://registry.npmjs.org/ioredis-mock/-/ioredis-mock-8.8.3.tgz",
+ "integrity": "sha512-LkF17WIyYkPfUhvp0fjIZ+HKhILEoq1J2b71vv+9EOW054UlkySVEvgQ2RolXM+eI759MteHtXQvv0oRn0lkUg==",
+ "dev": true,
+ "dependencies": {
+ "@ioredis/as-callback": "^3.0.0",
+ "@ioredis/commands": "^1.2.0",
+ "fengari": "^0.1.4",
+ "fengari-interop": "^0.1.3",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12.22"
+ },
+ "peerDependencies": {
+ "@types/ioredis-mock": "^8",
+ "ioredis": "^5"
+ }
+ },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"license": "MIT",
@@ -8423,6 +8522,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-stringify-pretty-compact": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
+ "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q=="
+ },
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"license": "ISC"
@@ -8679,7 +8783,6 @@
},
"node_modules/make-error": {
"version": "1.3.6",
- "devOptional": true,
"license": "ISC"
},
"node_modules/makeerror": {
@@ -10114,6 +10217,15 @@
"node": ">=8.10.0"
}
},
+ "node_modules/readline-sync": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
+ "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@@ -10551,8 +10663,9 @@
}
},
"node_modules/semver": {
- "version": "7.5.3",
- "license": "ISC",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -11389,7 +11502,6 @@
},
"node_modules/ts-node": {
"version": "10.9.1",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
@@ -11899,7 +12011,6 @@
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
- "devOptional": true,
"license": "MIT"
},
"node_modules/v8-to-istanbul": {
@@ -12355,7 +12466,6 @@
},
"node_modules/yn": {
"version": "3.1.1",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=6"
diff --git a/services/content-watcher/package.json b/services/content-watcher/package.json
index 9855c779..83804757 100644
--- a/services/content-watcher/package.json
+++ b/services/content-watcher/package.json
@@ -37,6 +37,8 @@
},
"homepage": "https://github.com/AmplicaLabs/content-publishing-service#readme",
"dependencies": {
+ "@dsnp/activity-content": "^1.1.0",
+ "@dsnp/frequency-schemas": "^1.0.2",
"@dsnp/parquetjs": "^1.3.4",
"@frequency-chain/api-augment": "1.7.0",
"@jest/globals": "^29.5.0",
@@ -71,7 +73,7 @@
"ipfs-only-hash": "^4.0.0",
"joi": "^17.9.1",
"mime-types": "^2.1.35",
- "multiformats": "^9.9.0",
+ "multiformats": "9.9.0",
"rxjs": "^7.8.1",
"time-constants": "^1.0.3"
},
@@ -95,6 +97,7 @@
"eslint-plugin-nestjs": "^1.2.3",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
+ "ioredis-mock": "^8.8.3",
"jest": "^29.5.0",
"license-report": "^6.4.0",
"prettier": "^3.0.2",
From 14da29bcbbf2cef0cd9a730b669725597f8e4047 Mon Sep 17 00:00:00 2001
From: Aramik
Date: Wed, 6 Sep 2023 16:41:35 -0700
Subject: [PATCH 014/137] adde e2e tests for assets (#35)
* adde e2e tests for assets
* removed console log
---
.../apps/api/src/api.controller.ts | 1 +
.../apps/api/src/api.module.ts | 3 +-
.../apps/api/src/development.controller.ts | 19 +-
.../apps/api/test/app.e2e-spec.ts | 308 +++++++++++++++++-
.../asset.processor.service.ts | 2 +-
.../request.processor.service.ts | 1 -
services/content-watcher/env.template | 7 +
.../libs/common/src/utils/ipfs.client.ts | 2 +-
8 files changed, 320 insertions(+), 23 deletions(-)
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index ea7518f6..6600c870 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -48,6 +48,7 @@ export class ApiController {
.addFileTypeValidator({
fileType: DSNP_VALID_MIME_TYPES,
})
+ // TODO: add a validator to check overall uploaded size
.addMaxSizeValidator({
// this is in bytes (2 GB)
maxSize: 2 * 1000 * 1000 * 1000,
diff --git a/services/content-watcher/apps/api/src/api.module.ts b/services/content-watcher/apps/api/src/api.module.ts
index 83492bd7..55b8a956 100644
--- a/services/content-watcher/apps/api/src/api.module.ts
+++ b/services/content-watcher/apps/api/src/api.module.ts
@@ -9,6 +9,7 @@ import { ConfigModule } from './config/config.module';
import { DevelopmentController } from './development.controller';
import { QueueConstants } from '../../../libs/common/src';
import { ApiService } from './api.service';
+import { IpfsService } from '../../../libs/common/src/utils/ipfs.client';
@Module({
imports: [
@@ -54,7 +55,7 @@ import { ApiService } from './api.service';
}),
ScheduleModule.forRoot(),
],
- providers: [ConfigService, ApiService],
+ providers: [ConfigService, ApiService, IpfsService],
controllers: process.env?.ENABLE_DEV_CONTROLLER === 'true' ? [DevelopmentController, ApiController] : [ApiController],
exports: [],
})
diff --git a/services/content-watcher/apps/api/src/development.controller.ts b/services/content-watcher/apps/api/src/development.controller.ts
index 05ccdaec..ff657c4c 100644
--- a/services/content-watcher/apps/api/src/development.controller.ts
+++ b/services/content-watcher/apps/api/src/development.controller.ts
@@ -8,12 +8,16 @@ import { Controller, Logger, Post, Body, Param, Query, HttpException, HttpStatus
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
import { QueueConstants } from '../../../libs/common/src';
+import { IpfsService } from '../../../libs/common/src/utils/ipfs.client';
@Controller('api/dev')
export class DevelopmentController {
private readonly logger: Logger;
- constructor(@InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue) {
+ constructor(
+ @InjectQueue(QueueConstants.REQUEST_QUEUE_NAME) private requestQueue: Queue,
+ private ipfsService: IpfsService,
+ ) {
this.logger = new Logger(this.constructor.name);
}
@@ -24,4 +28,17 @@ export class DevelopmentController {
this.logger.log(job);
return job;
}
+
+ @Get('/asset/:assetId')
+ // eslint-disable-next-line consistent-return
+ async getAsset(@Param('assetId') assetId: string) {
+ try {
+ return this.ipfsService.getPinned(assetId);
+ } catch (error: any) {
+ if (error.response) {
+ console.error(error.response.data);
+ }
+ throw error;
+ }
+ }
}
diff --git a/services/content-watcher/apps/api/test/app.e2e-spec.ts b/services/content-watcher/apps/api/test/app.e2e-spec.ts
index b763942c..f83afc72 100644
--- a/services/content-watcher/apps/api/test/app.e2e-spec.ts
+++ b/services/content-watcher/apps/api/test/app.e2e-spec.ts
@@ -4,11 +4,14 @@ import { INestApplication, ValidationPipe } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import request from 'supertest';
import { EventEmitter2 } from '@nestjs/event-emitter';
+import { randomFill } from 'crypto';
import { ApiModule } from '../src/api.module';
describe('AppController E2E request verification!', () => {
let app: INestApplication;
let module: TestingModule;
+ // eslint-disable-next-line no-promise-executor-return
+ const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
const validLocation = {
name: 'name of location',
accuracy: 97,
@@ -28,18 +31,25 @@ describe('AppController E2E request verification!', () => {
name: '#taggedUser',
},
];
- const validContentNoAssets = {
+ const validContentNoUploadedAssets = {
content: 'test broadcast message',
published: '1970-01-01T00:00:00+00:00',
name: 'name of note content',
+ assets: [
+ {
+ type: 'link',
+ name: 'link asset',
+ href: 'http://example.com',
+ },
+ ],
tag: validTags,
location: validLocation,
};
- const validBroadCastNoAssets = {
- content: validContentNoAssets,
+ const validBroadCastNoUploadedAssets = {
+ content: validContentNoUploadedAssets,
};
- const validReplyNoAssets = {
- content: validContentNoAssets,
+ const validReplyNoUploadedAssets = {
+ content: validContentNoUploadedAssets,
inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
const validReaction = {
@@ -47,7 +57,7 @@ describe('AppController E2E request verification!', () => {
apply: 5,
inReplyTo: 'dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
};
- const validProfileNoAssets = {
+ const validProfileNoUploadedAssets = {
summary: 'profile summary',
published: '1970-01-01T00:00:00+00:00',
name: 'name of profile content',
@@ -77,7 +87,7 @@ describe('AppController E2E request verification!', () => {
const invalidDsnpUserId = '2gsjhdaj';
return request(app.getHttpServer())
.post(`/api/content/${invalidDsnpUserId}/broadcast`)
- .send(validBroadCastNoAssets)
+ .send(validBroadCastNoUploadedAssets)
.expect(400)
.expect((res) => expect(res.text).toContain('must be a number string'));
});
@@ -92,13 +102,67 @@ describe('AppController E2E request verification!', () => {
});
describe('(POST) /api/content/:dsnpUserId/broadcast', () => {
- it('valid request without assets should work!', () =>
+ it('valid request without uploaded assets should work!', () =>
request(app.getHttpServer())
.post(`/api/content/123/broadcast`)
- .send(validBroadCastNoAssets)
+ .send(validBroadCastNoUploadedAssets)
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
+ it('valid request with uploaded assets should work!', async () => {
+ const file = Buffer.from('g'.repeat(30 * 1000 * 1000)); // 30MB
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', file, 'file1.jpg').expect(202);
+ await sleep(1000);
+ const validBroadCastWithUploadedAssets = {
+ content: {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: response.body.assetIds[0],
+ height: 123,
+ width: 321,
+ },
+ ],
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(validBroadCastWithUploadedAssets)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId'));
+ }, 15000);
+
+ it('request with not uploaded assets should fail!', async () => {
+ const badAssetCid = 'bafybeiap642764aat6txaap4qex4empkdtpjv7uabv47w1pdih3nflajpy';
+ const validBroadCastWithUploadedAssets = {
+ content: {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: badAssetCid,
+ },
+ ],
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/broadcast`)
+ .send(validBroadCastWithUploadedAssets)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain(`${badAssetCid} does not exist`));
+ });
+
it('empty body should fail', () => {
const body = {};
return request(app.getHttpServer())
@@ -349,10 +413,68 @@ describe('AppController E2E request verification!', () => {
it('valid request without assets should work!', () =>
request(app.getHttpServer())
.post(`/api/content/123/reply`)
- .send(validReplyNoAssets)
+ .send(validReplyNoUploadedAssets)
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
+ it('valid request with uploaded assets should work!', async () => {
+ const file = Buffer.from('h'.repeat(30 * 1000 * 1000)); // 30MB
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', file, 'file1.jpg').expect(202);
+ await sleep(1000);
+ const validReplyWithUploadedAssets = {
+ ...validReplyNoUploadedAssets,
+ content: {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: response.body.assetIds[0],
+ height: 123,
+ width: 321,
+ },
+ ],
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send(validReplyWithUploadedAssets)
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId'));
+ }, 15000);
+
+ it('request with not uploaded assets should fail!', async () => {
+ const badAssetCid = 'bafybeiap642764aat6txaap4qex4empkdtpjv7uabv47w1pdih3nflajpy';
+ const validReplyWithUploadedAssets = {
+ ...validReplyNoUploadedAssets,
+ content: {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: badAssetCid,
+ height: 123,
+ width: 321,
+ },
+ ],
+ },
+ ],
+ },
+ };
+ return request(app.getHttpServer())
+ .post(`/api/content/123/reply`)
+ .send(validReplyWithUploadedAssets)
+ .expect(400)
+ .expect((res) => expect(res.text).toContain(`${badAssetCid} does not exist`));
+ });
+
it('empty body should fail', () => {
const body = {};
return request(app.getHttpServer())
@@ -366,7 +488,7 @@ describe('AppController E2E request verification!', () => {
request(app.getHttpServer())
.post(`/api/content/123/reply`)
.send({
- content: validContentNoAssets,
+ content: validContentNoUploadedAssets,
})
.expect(400)
.expect((res) => expect(res.text).toContain('inReplyTo must be a string')));
@@ -375,7 +497,7 @@ describe('AppController E2E request verification!', () => {
request(app.getHttpServer())
.post(`/api/content/123/reply`)
.send({
- content: validContentNoAssets,
+ content: validContentNoUploadedAssets,
inReplyTo: 'shgdjas72gsjajasa',
})
.expect(400)
@@ -427,17 +549,73 @@ describe('AppController E2E request verification!', () => {
.put(`/api/content/123/0x7653423447AF`)
.send({
targetAnnouncementType: 'broadcast',
- content: validContentNoAssets,
+ content: validContentNoUploadedAssets,
})
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
+ it('valid request with uploaded assets should work!', async () => {
+ const file = Buffer.from('g'.repeat(30 * 1000 * 1000)); // 30MB
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', file, 'file1.jpg').expect(202);
+ await sleep(1000);
+ const validContentWithUploadedAssets = {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: response.body.assetIds[0],
+ height: 123,
+ width: 321,
+ },
+ ],
+ },
+ ],
+ };
+ return request(app.getHttpServer())
+ .put(`/api/content/123/0x7653423447AF`)
+ .send({
+ targetAnnouncementType: 'broadcast',
+ content: validContentWithUploadedAssets,
+ })
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId'));
+ }, 15000);
+
+ it('request with not uploaded assets should fail!', async () => {
+ const badAssetCid = 'bafybeiap642764aat6txaap4qex4empkdtpjv7uabv47w1pdih3nflajpy';
+ const validBroadCastWithUploadedAssets = {
+ ...validContentNoUploadedAssets,
+ assets: [
+ {
+ type: 'image',
+ name: 'image asset',
+ references: [
+ {
+ referenceId: badAssetCid,
+ },
+ ],
+ },
+ ],
+ };
+ return request(app.getHttpServer())
+ .put(`/api/content/123/0x7653423447AF`)
+ .send({
+ targetAnnouncementType: 'broadcast',
+ content: validBroadCastWithUploadedAssets,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain(`${badAssetCid} does not exist`));
+ });
+
it('invalid targetAnnouncementType should fail', () =>
request(app.getHttpServer())
.put(`/api/content/123/0x7653423447AF`)
.send({
targetAnnouncementType: 'invalid',
- content: validContentNoAssets,
+ content: validContentNoUploadedAssets,
})
.expect(400)
.expect((res) => expect(res.text).toContain('targetAnnouncementType must be one of the following values')));
@@ -456,11 +634,78 @@ describe('AppController E2E request verification!', () => {
request(app.getHttpServer())
.put(`/api/profile/123`)
.send({
- profile: validProfileNoAssets,
+ profile: validProfileNoUploadedAssets,
})
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
+ it('valid request with uploaded assets should work!', async () => {
+ const file = Buffer.from('n'.repeat(30 * 1000 * 1000)); // 30MB
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', file, 'file.jpg').expect(202);
+ await sleep(1000);
+ const validUploadWithUploadedAssets = {
+ ...validProfileNoUploadedAssets,
+ icon: [
+ {
+ referenceId: response.body.assetIds[0],
+ height: 123,
+ width: 321,
+ },
+ ],
+ };
+ return request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: validUploadWithUploadedAssets,
+ })
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('referenceId'));
+ }, 15000);
+
+ it('request with not uploaded icon should fail!', async () => {
+ const badAssetCid = 'bafybeiap642764aat6txaap4qex4empkdtpjv7uabv47w1pdih3nflajpy';
+ const validUploadWithUploadedAssets = {
+ ...validProfileNoUploadedAssets,
+ icon: [
+ {
+ referenceId: badAssetCid,
+ height: 123,
+ width: 321,
+ },
+ ],
+ };
+ return request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: validUploadWithUploadedAssets,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain(`${badAssetCid} does not exist`));
+ });
+
+ it('request with non-image uploaded assets should fail!', async () => {
+ const file = Buffer.from('s'.repeat(30 * 1000 * 1000)); // 30MB
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', file, 'file.mp3').expect(202);
+ await sleep(1000);
+ const profileContent = {
+ ...validProfileNoUploadedAssets,
+ icon: [
+ {
+ referenceId: response.body.assetIds[0],
+ height: 123,
+ width: 321,
+ },
+ ],
+ };
+ return request(app.getHttpServer())
+ .put(`/api/profile/123`)
+ .send({
+ profile: profileContent,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('is not an image!'));
+ }, 15000);
+
it('empty profile should fail', () =>
request(app.getHttpServer())
.put(`/api/profile/123`)
@@ -502,16 +747,43 @@ describe('AppController E2E request verification!', () => {
it('valid request should work!', () =>
request(app.getHttpServer())
.put(`/api/asset/upload`)
- .attach('files', Buffer.from(validContentNoAssets.toString()), 'image.jpg')
+ .attach('files', Buffer.from(validContentNoUploadedAssets.toString()), 'image.jpg')
.expect(202)
.expect((res) => expect(res.text).toContain('assetIds')));
it('invalid mime should fail', () =>
request(app.getHttpServer())
.put(`/api/asset/upload`)
- .attach('files', Buffer.from(validContentNoAssets.toString()), 'doc.txt')
+ .attach('files', Buffer.from(validContentNoUploadedAssets.toString()), 'doc.txt')
.expect(422)
.expect((res) => expect(res.text).toContain('expected type is')));
+
+ it('valid request should work!', async () => {
+ const file1 = Buffer.from('a'.repeat(30 * 1000)); // 30KB
+ const file2 = Buffer.from('t'.repeat(30 * 1000 * 1000)); // 30MB
+ const file3 = Buffer.from('z'.repeat(100 * 1000 * 1000)); // 100MB
+ await request(app.getHttpServer())
+ .put(`/api/asset/upload`)
+ .attach('files', file1, 'file1.jpg')
+ .attach('files', file2, 'file2.mp3')
+ .attach('files', file3, 'file3.mpeg')
+ .expect(202)
+ .expect((res) => expect(res.text).toContain('assetIds'));
+ }, 15000);
+
+ it('upload asset should be uploaded to IPFS', async () => {
+ const buffer = new Uint32Array(100 * 1000);
+ randomFill(buffer, (err, buf) => {
+ if (err) throw err;
+ });
+ const response = await request(app.getHttpServer()).put(`/api/asset/upload`).attach('files', Buffer.from(buffer), 'file1.jpg').expect(202);
+ const assetId = response.body.assetIds[0];
+ await sleep(2000);
+ return request(app.getHttpServer())
+ .get(`/api/dev/asset/${assetId}`)
+ .expect(200)
+ .expect((res) => expect(Buffer.from(res.body)).toEqual(Buffer.from(buffer)));
+ }, 15000);
});
afterEach(async () => {
@@ -520,5 +792,5 @@ describe('AppController E2E request verification!', () => {
} catch (err) {
console.error(err);
}
- });
+ }, 15000);
});
diff --git a/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
index 045850c0..4617bfcb 100644
--- a/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
+++ b/services/content-watcher/apps/worker/src/asset_processor/asset.processor.service.ts
@@ -43,7 +43,7 @@ export class AssetProcessorService extends WorkerHost {
const secondsPassed = Math.round((Date.now() - job.timestamp) / 1000);
const expectedSecondsToExpire = 5 * 60; // TODO: get from config
const secondsToExpire = Math.max(0, expectedSecondsToExpire - secondsPassed);
- const result = await this.redis.pipeline().del(job.data.contentLocation).expire(job.data.metadataLocation, secondsToExpire, 'LT').exec();
+ const result = await this.redis.pipeline().expire(job.data.contentLocation, secondsToExpire, 'LT').expire(job.data.metadataLocation, secondsToExpire, 'LT').exec();
this.logger.debug(result);
}
}
diff --git a/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
index 1abfca4f..1bf598d0 100644
--- a/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
+++ b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
@@ -28,7 +28,6 @@ export class RequestProcessorService extends WorkerHost {
const pinnedAssets = assets.map((cid) => this.ipfsService.getPinned(cid));
const pinnedResult = await Promise.all(pinnedAssets);
- this.logger.debug(pinnedResult);
// if any of assets does not exists delay the job for a future attempt
if (pinnedResult.some((buffer) => !buffer)) {
await this.delayJobAndIncrementAttempts(job);
diff --git a/services/content-watcher/env.template b/services/content-watcher/env.template
index bc6fd8a1..7ce43d61 100644
--- a/services/content-watcher/env.template
+++ b/services/content-watcher/env.template
@@ -16,3 +16,10 @@ HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS=10
HEALTH_CHECK_MAX_RETRIES=4
CAPACITY_LIMIT='{"type":"percentage", "value":80}'
+IPFS_ENDPOINT="http://127.0.0.1:5001"
+IPFS_BASIC_AUTH_USER=""
+IPFS_BASIC_AUTH_SECRET=""
+IPFS_GATEWAY_URL="http://127.0.0.1:8080/ipfs/[CID]"
+
+# should be enabled for e2e tests
+# ENABLE_DEV_CONTROLLER=true
\ No newline at end of file
diff --git a/services/content-watcher/libs/common/src/utils/ipfs.client.ts b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
index 7cc9c320..68107c5f 100644
--- a/services/content-watcher/libs/common/src/utils/ipfs.client.ts
+++ b/services/content-watcher/libs/common/src/utils/ipfs.client.ts
@@ -88,7 +88,7 @@ export class IpfsService {
authorization: ipfsAuth,
};
- const response = await axios.post(ipfsGet, null, { headers, responseType: 'arraybuffer' });
+ const response = await axios.post(ipfsGet, null, { headers, responseType: 'blob' });
const { data } = response;
return data;
From dc1fdd12c32c5ba3a5d22e9aea06a5f1090615e4 Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Wed, 6 Sep 2023 18:43:26 -0500
Subject: [PATCH 015/137] bug fix (#36)
---
.../worker/src/batch_announcer/batch.announcer.spec.ts | 2 +-
.../apps/worker/src/batch_announcer/batch.announcer.ts | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
index 52ffefdc..edd37793 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
@@ -72,7 +72,7 @@ describe('BatchAnnouncer', () => {
mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
mockBlockchainService.getSchema.mockReturnValue({ model: JSON.stringify(broadcast) });
mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
- mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', size: 'mockSize' });
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', size: 10, hash: 'mockHash' });
const batchJob = {
batchId: 'mockBatchId',
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
index 1f39cedf..bbb07956 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.ts
@@ -55,11 +55,11 @@ export class BatchAnnouncer {
await writer.close();
const buffer = await this.bufferPublishStream(publishStream);
- const [cid, hash] = await this.pinStringToIPFS(buffer);
+ const [cid, hash, size] = await this.pinParquetFileToIPFS(buffer);
const ipfsUrl = await this.formIpfsUrl(cid);
this.logger.debug(`Batch ${batchId} published to IPFS at ${ipfsUrl}`);
this.logger.debug(`Batch ${batchId} hash: ${hash}`);
- return { id: batchId, schemaId, data: { cid, payloadLength: buffer.length } };
+ return { id: batchId, schemaId, data: { cid, payloadLength: size } };
}
private async bufferPublishStream(publishStream: PassThrough): Promise {
@@ -78,9 +78,9 @@ export class BatchAnnouncer {
});
}
- private async pinStringToIPFS(buf: Buffer): Promise<[string, string]> {
- const { cid, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
- return [cid.toString(), size.toString()];
+ private async pinParquetFileToIPFS(buf: Buffer): Promise<[string, string, number]> {
+ const { cid, hash, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
+ return [cid.toString(), hash, size];
}
private async formIpfsUrl(cid: string): Promise {
From 5a46124a89f4092beb50269cb25f56f771767867 Mon Sep 17 00:00:00 2001
From: Aramik
Date: Thu, 7 Sep 2023 12:36:28 -0700
Subject: [PATCH 016/137] fix tombstone contract (#38)
* fix tombstone contract
* fixed e2e tests
* comment fix
* comment fix
---
.../apps/api/src/api.controller.ts | 14 ++---
.../apps/api/src/api.service.ts | 5 +-
.../content-watcher/apps/api/src/metadata.ts | 2 +-
.../apps/api/test/app.e2e-spec.ts | 61 ++++++++++++++-----
.../batch_announcer/batch.announcer.spec.ts | 2 +
.../libs/common/src/dtos/announcement.dto.ts | 29 ++++++---
.../libs/common/src/dtos/common.dto.ts | 8 +--
.../libs/common/src/dtos/validation.dto.ts | 5 ++
.../src/interfaces/request-job.interface.ts | 1 -
9 files changed, 86 insertions(+), 41 deletions(-)
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index 6600c870..c06586b0 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -8,12 +8,12 @@ import {
AssetIncludedRequestDto,
BroadcastDto,
DSNP_VALID_MIME_TYPES,
- DsnpContentHashParam,
DsnpUserIdParam,
FilesUploadDto,
ProfileDto,
ReactionDto,
ReplyDto,
+ TombstoneDto,
UpdateDto,
UploadResponseDto,
} from '../../../libs/common/src';
@@ -83,17 +83,17 @@ export class ApiController {
return this.apiService.enqueueRequest(AnnouncementTypeDto.REACTION, userDsnpId.userDsnpId, reactionDto);
}
- @Put('content/:userDsnpId/:targetContentHash')
+ @Put('content/:userDsnpId')
@HttpCode(202)
- async update(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam, @Body() updateDto: UpdateDto): Promise {
+ async update(@Param() userDsnpId: DsnpUserIdParam, @Body() updateDto: UpdateDto): Promise {
await this.apiService.validateAssets(updateDto as AssetIncludedRequestDto);
- return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto, targetContentHash.targetContentHash);
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto);
}
- @Delete('content/:userDsnpId/:targetContentHash')
+ @Delete('content/:userDsnpId')
@HttpCode(202)
- async delete(@Param() userDsnpId: DsnpUserIdParam, @Param() targetContentHash: DsnpContentHashParam): Promise {
- return this.apiService.enqueueRequest(AnnouncementTypeDto.TOMBSTONE, userDsnpId.userDsnpId, undefined, targetContentHash.targetContentHash);
+ async delete(@Param() userDsnpId: DsnpUserIdParam, @Body() tombstoneDto: TombstoneDto): Promise {
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.TOMBSTONE, userDsnpId.userDsnpId, tombstoneDto);
}
@Put('profile/:userDsnpId')
diff --git a/services/content-watcher/apps/api/src/api.service.ts b/services/content-watcher/apps/api/src/api.service.ts
index ee1abbc9..d985757f 100644
--- a/services/content-watcher/apps/api/src/api.service.ts
+++ b/services/content-watcher/apps/api/src/api.service.ts
@@ -1,5 +1,5 @@
import { InjectQueue } from '@nestjs/bullmq';
-import { BadRequestException, Injectable, Logger } from '@nestjs/common';
+import { Injectable, Logger } from '@nestjs/common';
import { Queue } from 'bullmq';
import { createHash } from 'crypto';
import { BulkJobOptions } from 'bullmq/dist/esm/interfaces';
@@ -34,13 +34,12 @@ export class ApiService {
this.logger = new Logger(this.constructor.name);
}
- async enqueueRequest(announcementType: AnnouncementTypeDto, dsnpUserId: string, content?: RequestTypeDto, targetContentHash?: string): Promise {
+ async enqueueRequest(announcementType: AnnouncementTypeDto, dsnpUserId: string, content?: RequestTypeDto): Promise {
const data = {
content,
id: '',
announcementType,
dsnpUserId,
- targetContentHash,
dependencyAttempt: 0,
} as IRequestJob;
data.id = this.calculateJobId(data);
diff --git a/services/content-watcher/apps/api/src/metadata.ts b/services/content-watcher/apps/api/src/metadata.ts
index 9577d58d..530eafc4 100644
--- a/services/content-watcher/apps/api/src/metadata.ts
+++ b/services/content-watcher/apps/api/src/metadata.ts
@@ -5,5 +5,5 @@ export default async () => {
["../../../libs/common/src/dtos/announcement.dto"]: await import("../../../libs/common/src/dtos/announcement.dto"),
["../../../libs/common/src/dtos/common.dto"]: await import("../../../libs/common/src/dtos/common.dto")
};
- return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LocationDto": { name: { required: true, type: () => String, minLength: 1 }, accuracy: { required: false, type: () => Number, minimum: 0, maximum: 100 }, altitude: { required: false, type: () => Number }, latitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number, minimum: 0 }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String, minLength: 1 }, height: { required: false, type: () => Number, minimum: 1 }, width: { required: false, type: () => Number, minimum: 1 }, duration: { required: false, type: () => String, pattern: "DURATION_REGEX" } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String, minLength: 1 }, mentionedId: { required: false, type: () => String, minLength: 1, pattern: "DSNP_USER_URI_REGEX" } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String, minLength: 1 }, href: { required: false, type: () => String, minLength: 1 } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String, minLength: 1 }, published: { required: true, type: () => String, pattern: "ISO8601_REGEX" }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String, pattern: "ISO8601_REGEX" } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "UpdateDto": { targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].UpdateAnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String, minLength: 1, pattern: "DSNP_EMOJI_REGEX" }, apply: { required: true, type: () => Number, minimum: 0, maximum: 255 }, inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "DsnpUserIdParam": { userDsnpId: { required: true, type: () => String } }, "DsnpContentHashParam": { targetContentHash: { required: true, type: () => String } }, "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }], [import("./development.controller"), { "DevelopmentController": { "requestJob": {} } }]] } };
+ return { "@nestjs/swagger": { "models": [[import("../../../libs/common/src/dtos/activity.dto"), { "LocationDto": { name: { required: true, type: () => String, minLength: 1 }, accuracy: { required: false, type: () => Number, minimum: 0, maximum: 100 }, altitude: { required: false, type: () => Number }, latitude: { required: false, type: () => Number }, longitude: { required: false, type: () => Number }, radius: { required: false, type: () => Number, minimum: 0 }, units: { required: false, enum: t["../../../libs/common/src/dtos/activity.dto"].UnitTypeDto } }, "AssetReferenceDto": { referenceId: { required: true, type: () => String, minLength: 1 }, height: { required: false, type: () => Number, minimum: 1 }, width: { required: false, type: () => Number, minimum: 1 }, duration: { required: false, type: () => String, pattern: "DURATION_REGEX" } }, "TagDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].TagTypeDto }, name: { required: false, type: () => String, minLength: 1 }, mentionedId: { required: false, type: () => String, minLength: 1, pattern: "DSNP_USER_URI_REGEX" } }, "AssetDto": { type: { required: true, enum: t["../../../libs/common/src/dtos/activity.dto"].AttachmentTypeDto }, references: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, name: { required: false, type: () => String, minLength: 1 }, href: { required: false, type: () => String, minLength: 1 } }, "BaseActivityDto": { name: { required: false, type: () => String }, tag: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].TagDto] }, location: { required: false, type: () => t["../../../libs/common/src/dtos/activity.dto"].LocationDto } }, "NoteActivityDto": { content: { required: true, type: () => String, minLength: 1 }, published: { required: true, type: () => String, pattern: "ISO8601_REGEX" }, assets: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetDto] } }, "ProfileActivityDto": { icon: { required: false, type: () => [t["../../../libs/common/src/dtos/activity.dto"].AssetReferenceDto] }, summary: { required: false, type: () => String }, published: { required: false, type: () => String, pattern: "ISO8601_REGEX" } } }], [import("../../../libs/common/src/dtos/announcement.dto"), { "BroadcastDto": { content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReplyDto": { inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "TombstoneDto": { targetContentHash: { required: true, type: () => String, pattern: "DSNP_CONTENT_HASH_REGEX" }, targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].ModifiableAnnouncementTypeDto } }, "UpdateDto": { targetContentHash: { required: true, type: () => String, pattern: "DSNP_CONTENT_HASH_REGEX" }, targetAnnouncementType: { required: true, enum: t["../../../libs/common/src/dtos/announcement.dto"].ModifiableAnnouncementTypeDto }, content: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].NoteActivityDto } }, "ReactionDto": { emoji: { required: true, type: () => String, minLength: 1, pattern: "DSNP_EMOJI_REGEX" }, apply: { required: true, type: () => Number, minimum: 0, maximum: 255 }, inReplyTo: { required: true, type: () => String, pattern: "DSNP_CONTENT_URI_REGEX" } }, "ProfileDto": { profile: { required: true, type: () => t["../../../libs/common/src/dtos/activity.dto"].ProfileActivityDto } } }], [import("../../../libs/common/src/dtos/common.dto"), { "DsnpUserIdParam": { userDsnpId: { required: true, type: () => String } }, "AnnouncementResponseDto": { referenceId: { required: true, type: () => String } }, "UploadResponseDto": { assetIds: { required: true, type: () => [String] } }, "FilesUploadDto": { files: { required: true, type: () => [Object] } } }]], "controllers": [[import("./api.controller"), { "ApiController": { "health": {}, "assetUpload": { type: t["../../../libs/common/src/dtos/common.dto"].UploadResponseDto }, "broadcast": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reply": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "reaction": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "update": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "delete": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto }, "profile": { type: t["../../../libs/common/src/dtos/common.dto"].AnnouncementResponseDto } } }], [import("./development.controller"), { "DevelopmentController": { "requestJob": {}, "getAsset": { type: Object } } }]] } };
};
\ No newline at end of file
diff --git a/services/content-watcher/apps/api/test/app.e2e-spec.ts b/services/content-watcher/apps/api/test/app.e2e-spec.ts
index f83afc72..8aba5856 100644
--- a/services/content-watcher/apps/api/test/app.e2e-spec.ts
+++ b/services/content-watcher/apps/api/test/app.e2e-spec.ts
@@ -91,14 +91,6 @@ describe('AppController E2E request verification!', () => {
.expect(400)
.expect((res) => expect(res.text).toContain('must be a number string'));
});
-
- it('invalid DsnpContentHashParam should fail', () => {
- const invalidContentHashParam = '2gsjhdaj';
- return request(app.getHttpServer())
- .delete(`/api/content/123/${invalidContentHashParam}`)
- .expect(400)
- .expect((res) => expect(res.text).toContain('must be in hexadecimal format'));
- });
});
describe('(POST) /api/content/:dsnpUserId/broadcast', () => {
@@ -543,11 +535,12 @@ describe('AppController E2E request verification!', () => {
.expect((res) => expect(res.text).toContain('inReplyTo must match')));
});
- describe('(PUT) /api/content/:dsnpUserId/:contentHash', () => {
+ describe('(PUT) /api/content/:dsnpUserId', () => {
it('valid request without assets should work!', () =>
request(app.getHttpServer())
- .put(`/api/content/123/0x7653423447AF`)
+ .put(`/api/content/123`)
.send({
+ targetContentHash: '0x7653423447AF',
targetAnnouncementType: 'broadcast',
content: validContentNoUploadedAssets,
})
@@ -575,8 +568,9 @@ describe('AppController E2E request verification!', () => {
],
};
return request(app.getHttpServer())
- .put(`/api/content/123/0x7653423447AF`)
+ .put(`/api/content/123`)
.send({
+ targetContentHash: '0x7653423447AF',
targetAnnouncementType: 'broadcast',
content: validContentWithUploadedAssets,
})
@@ -601,8 +595,9 @@ describe('AppController E2E request verification!', () => {
],
};
return request(app.getHttpServer())
- .put(`/api/content/123/0x7653423447AF`)
+ .put(`/api/content/123`)
.send({
+ targetContentHash: '0x7653423447AF',
targetAnnouncementType: 'broadcast',
content: validBroadCastWithUploadedAssets,
})
@@ -612,21 +607,57 @@ describe('AppController E2E request verification!', () => {
it('invalid targetAnnouncementType should fail', () =>
request(app.getHttpServer())
- .put(`/api/content/123/0x7653423447AF`)
+ .put(`/api/content/123`)
.send({
+ targetContentHash: '0x7653423447AF',
targetAnnouncementType: 'invalid',
content: validContentNoUploadedAssets,
})
.expect(400)
.expect((res) => expect(res.text).toContain('targetAnnouncementType must be one of the following values')));
+
+ it('invalid targetContentHash should fail', () =>
+ request(app.getHttpServer())
+ .put(`/api/content/123`)
+ .send({
+ targetContentHash: '6328462378',
+ targetAnnouncementType: 'reply',
+ content: validContentNoUploadedAssets,
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('targetContentHash must be in hexadecimal format!')));
});
- describe('(DELETE) /api/content/:dsnpUserId/contentHash', () => {
+ describe('(DELETE) /api/content/:dsnpUserId', () => {
it('valid request should work!', () =>
request(app.getHttpServer())
- .delete(`/api/content/123/0x7653423447AF`)
+ .delete(`/api/content/123`)
+ .send({
+ targetContentHash: '0x7653423447AF',
+ targetAnnouncementType: 'reply',
+ })
.expect(202)
.expect((res) => expect(res.text).toContain('referenceId')));
+
+ it('invalid targetAnnouncementType should fail', () =>
+ request(app.getHttpServer())
+ .delete(`/api/content/123`)
+ .send({
+ targetContentHash: '0x7653423447AF',
+ targetAnnouncementType: 'invalid',
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('targetAnnouncementType must be one of the following values')));
+
+ it('invalid targetContentHash should fail', () =>
+ request(app.getHttpServer())
+ .delete(`/api/content/123`)
+ .send({
+ targetContentHash: '6328462378',
+ targetAnnouncementType: 'reply',
+ })
+ .expect(400)
+ .expect((res) => expect(res.text).toContain('targetContentHash must be in hexadecimal format!')));
});
describe('(PUT) /api/profile/:userDsnpId', () => {
diff --git a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
index edd37793..58e022d2 100644
--- a/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
+++ b/services/content-watcher/apps/worker/src/batch_announcer/batch.announcer.spec.ts
@@ -1,6 +1,8 @@
import { expect, describe, jest, it, beforeEach } from '@jest/globals';
import assert from 'assert';
+// eslint-disable-next-line import/no-extraneous-dependencies
import { FrequencyParquetSchema } from '@dsnp/frequency-schemas/types/frequency';
+// eslint-disable-next-line import/no-extraneous-dependencies
import Redis from 'ioredis-mock';
import { BatchAnnouncer } from './batch.announcer';
diff --git a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
index d9464527..7cf3c587 100644
--- a/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/announcement.dto.ts
@@ -2,13 +2,13 @@
* File name should always end with `.dto.ts` for swagger metadata generator to get picked up
*/
// eslint-disable-next-line max-classes-per-file
-import { IsEnum, IsInt, IsNotEmpty, IsString, Matches, Max, MaxLength, Min, MinLength, ValidateNested } from 'class-validator';
+import { IsEnum, IsHexadecimal, IsInt, IsNotEmpty, IsString, Matches, Max, MaxLength, Min, MinLength, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
import { NoteActivityDto, ProfileActivityDto } from './activity.dto';
-import { DSNP_CONTENT_URI_REGEX, DSNP_EMOJI_REGEX } from './validation.dto';
+import { DSNP_CONTENT_HASH_REGEX, DSNP_CONTENT_URI_REGEX, DSNP_EMOJI_REGEX } from './validation.dto';
// eslint-disable-next-line no-shadow
-export enum UpdateAnnouncementTypeDto {
+export enum ModifiableAnnouncementTypeDto {
BROADCAST = 'broadcast',
REPLY = 'reply',
}
@@ -31,9 +31,24 @@ export class ReplyDto {
content: NoteActivityDto;
}
+export class TombstoneDto {
+ @IsString()
+ @IsNotEmpty()
+ @Matches(DSNP_CONTENT_HASH_REGEX, { message: 'targetContentHash must be in hexadecimal format!' })
+ targetContentHash: string;
+
+ @IsEnum(ModifiableAnnouncementTypeDto)
+ targetAnnouncementType: ModifiableAnnouncementTypeDto;
+}
+
export class UpdateDto {
- @IsEnum(UpdateAnnouncementTypeDto)
- targetAnnouncementType: UpdateAnnouncementTypeDto;
+ @IsString()
+ @IsNotEmpty()
+ @Matches(DSNP_CONTENT_HASH_REGEX, { message: 'targetContentHash must be in hexadecimal format!' })
+ targetContentHash: string;
+
+ @IsEnum(ModifiableAnnouncementTypeDto)
+ targetAnnouncementType: ModifiableAnnouncementTypeDto;
@IsNotEmpty()
@ValidateNested()
@@ -64,5 +79,5 @@ export class ProfileDto {
profile: ProfileActivityDto;
}
-export type RequestTypeDto = BroadcastDto | ReplyDto | ReactionDto | UpdateDto | ProfileDto;
-export type AssetIncludedRequestDto = BroadcastDto & ReplyDto & UpdateDto & ProfileDto;
+export type RequestTypeDto = BroadcastDto | ReplyDto | ReactionDto | UpdateDto | ProfileDto | TombstoneDto;
+export type AssetIncludedRequestDto = BroadcastDto & ReplyDto & UpdateDto & ProfileDto & TombstoneDto;
diff --git a/services/content-watcher/libs/common/src/dtos/common.dto.ts b/services/content-watcher/libs/common/src/dtos/common.dto.ts
index 68040caf..dc1ddadd 100644
--- a/services/content-watcher/libs/common/src/dtos/common.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/common.dto.ts
@@ -3,7 +3,7 @@
*/
// eslint-disable-next-line max-classes-per-file
import { ApiProperty } from '@nestjs/swagger';
-import { IsHexadecimal, IsNotEmpty, IsNumberString } from 'class-validator';
+import { IsNotEmpty, IsNumberString } from 'class-validator';
export class DsnpUserIdParam {
@IsNotEmpty()
@@ -11,12 +11,6 @@ export class DsnpUserIdParam {
userDsnpId: string;
}
-export class DsnpContentHashParam {
- @IsNotEmpty()
- @IsHexadecimal({ message: 'targetContentHash must be in hexadecimal format!' })
- targetContentHash: string;
-}
-
export class AnnouncementResponseDto {
referenceId: string;
}
diff --git a/services/content-watcher/libs/common/src/dtos/validation.dto.ts b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
index 3b2e0fee..9df5b40c 100644
--- a/services/content-watcher/libs/common/src/dtos/validation.dto.ts
+++ b/services/content-watcher/libs/common/src/dtos/validation.dto.ts
@@ -7,6 +7,11 @@
* - example: 1970-01-01T00:00:00+00:00
*/
export const ISO8601_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{1,})?(Z|[+-][01][0-9]:[0-5][0-9])?$/;
+/**
+ * DSNP content hash based on DSNP Spec
+ * example: 0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+ */
+export const DSNP_CONTENT_HASH_REGEX = /^0x[0-9a-f]+$/i;
/**
* DSNP user URI based on DSNP Spec
* example: dsnp://78187493520
diff --git a/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
index 55593ec5..fb44bf05 100644
--- a/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
+++ b/services/content-watcher/libs/common/src/interfaces/request-job.interface.ts
@@ -5,7 +5,6 @@ export interface IRequestJob {
id: string;
announcementType: AnnouncementTypeDto;
dsnpUserId: string;
- targetContentHash?: string;
content?: RequestTypeDto;
dependencyAttempt: number;
}
From c7548c1f6b428d98a15bb5579d8cae4bd27c338a Mon Sep 17 00:00:00 2001
From: Puneet Saraswat <61435908+saraswatpuneet@users.noreply.github.com>
Date: Fri, 8 Sep 2023 14:02:09 -0500
Subject: [PATCH 017/137] Request processor to queue respective announcements
(#37)
* request processor
* queue announcements
* cleanup
* add unit test/ add todo
* fix tombstone contract
* mimeType for assest required
* address some feedback
* feedback
* refactor
* address feedback
* fix tags
* lint
* add unit tests
* add more tests
* cleanup/lint
* Update apps/worker/src/request_processor/dsnp.announcement.processor.ts
Co-authored-by: Aramik
---------
Co-authored-by: Aramik
---
.../dsnp.announcement.processor.spec.ts | 204 ++++++++++
.../dsnp.announcement.processor.ts | 383 ++++++++++++++++++
.../request.processor.module.ts | 23 +-
.../request.processor.service.ts | 30 +-
.../libs/common/src/interfaces/dsnp.ts | 42 +-
.../common/src/utils/dsnpTypeConverter.ts | 176 --------
6 files changed, 664 insertions(+), 194 deletions(-)
create mode 100644 services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.spec.ts
create mode 100644 services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.ts
delete mode 100644 services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
diff --git a/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.spec.ts b/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.spec.ts
new file mode 100644
index 00000000..42119ad1
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.spec.ts
@@ -0,0 +1,204 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { Queue } from 'bullmq';
+import { expect, describe, it, beforeEach, jest } from '@jest/globals';
+import { DsnpAnnouncementProcessor } from './dsnp.announcement.processor';
+import { AnnouncementTypeDto, IRequestJob, ModifiableAnnouncementTypeDto, TagTypeDto } from '../../../../libs/common/src';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+
+const mockQueue = {
+ add: jest.fn(),
+};
+
+// Mock the ConfigService class
+const mockConfigService = {
+ getIpfsCidPlaceholder: jest.fn(),
+};
+
+// Mock the IpfsService class
+const mockIpfsService = {
+ getPinned: jest.fn(),
+ ipfsPin: jest.fn(),
+};
+
+describe('DsnpAnnouncementProcessor', () => {
+ let dsnpAnnouncementProcessor: DsnpAnnouncementProcessor;
+ let module: TestingModule;
+
+ beforeEach(async () => {
+ module = await Test.createTestingModule({
+ providers: [
+ DsnpAnnouncementProcessor,
+ { provide: ConfigService, useValue: mockConfigService },
+ { provide: IpfsService, useValue: mockIpfsService },
+ { provide: Queue, useValue: mockQueue },
+ { provide: 'BullQueue_assetQueue', useValue: mockQueue },
+ { provide: 'BullQueue_broadcastQueue', useValue: mockQueue },
+ { provide: 'BullQueue_replyQueue', useValue: mockQueue },
+ { provide: 'BullQueue_reactionQueue', useValue: mockQueue },
+ { provide: 'BullQueue_updateQueue', useValue: mockQueue },
+ { provide: 'BullQueue_profileQueue', useValue: mockQueue },
+ { provide: 'BullQueue_tombstoneQueue', useValue: mockQueue },
+ ],
+ }).compile();
+
+ dsnpAnnouncementProcessor = module.get(DsnpAnnouncementProcessor);
+ });
+
+ it('should be defined', () => {
+ expect(dsnpAnnouncementProcessor).toBeDefined();
+ });
+
+ it('should collect and queue a broadcast announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '1',
+ announcementType: AnnouncementTypeDto.BROADCAST,
+ dsnpUserId: 'dsnp://123',
+ dependencyAttempt: 0,
+ content: {
+ content: {
+ content: 'mockContent',
+ published: '2021-01-01T00:00:00.000Z',
+ },
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+ it('should collect and queue a reply announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '2',
+ announcementType: AnnouncementTypeDto.REPLY,
+ dsnpUserId: 'dsnp://456',
+ dependencyAttempt: 0,
+ content: {
+ content: {
+ content: 'mockReplyContent',
+ published: '2021-01-01T00:00:00.000Z',
+ },
+ inReplyTo: 'dsnp://123/reply/1',
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+
+ it('should collect and queue a reaction announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '3',
+ announcementType: AnnouncementTypeDto.REACTION,
+ dsnpUserId: 'dsnp://789',
+ dependencyAttempt: 0,
+ content: {
+ emoji: '👍',
+ inReplyTo: 'dsnp://123/reply/1',
+ apply: 10,
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+ it('should collect and queue an update announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '4',
+ announcementType: AnnouncementTypeDto.UPDATE,
+ dsnpUserId: 'dsnp://101',
+ dependencyAttempt: 0,
+ content: {
+ content: {
+ content: 'mockUpdateContent',
+ published: '2021-01-01T00:00:00.000Z',
+ },
+ targetAnnouncementType: ModifiableAnnouncementTypeDto.REPLY,
+ targetContentHash: 'dsnp://123/reply/1',
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+
+ it('should collect and queue a profile announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '5',
+ announcementType: AnnouncementTypeDto.PROFILE,
+ dsnpUserId: 'dsnp://789',
+ dependencyAttempt: 0,
+ content: {
+ profile: {
+ name: 'John Doe',
+ published: '2021-01-01T00:00:00.000Z',
+ summary: 'A brief summary',
+ tag: [
+ { type: TagTypeDto.Hashtag, name: 'tag1' },
+ { type: TagTypeDto.Mention, name: 'user1', mentionedId: 'dsnp://123' },
+ ],
+ },
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+
+ it('should collect and queue a tombstone announcement', async () => {
+ // Mock the necessary dependencies' behavior
+ mockConfigService.getIpfsCidPlaceholder.mockReturnValue('mockIpfsUrl');
+ mockIpfsService.getPinned.mockReturnValue(Buffer.from('mockContentBuffer'));
+ mockIpfsService.ipfsPin.mockReturnValue({ cid: 'mockCid', hash: 'mockHash', size: 123 });
+
+ const data: IRequestJob = {
+ id: '6',
+ announcementType: AnnouncementTypeDto.TOMBSTONE,
+ dsnpUserId: 'dsnp://999',
+ dependencyAttempt: 0,
+ content: {
+ targetAnnouncementType: ModifiableAnnouncementTypeDto.BROADCAST,
+ targetContentHash: 'dsnp://123/broadcast/1',
+ },
+ };
+
+ await dsnpAnnouncementProcessor.collectAnnouncementAndQueue(data);
+
+ expect(mockConfigService.getIpfsCidPlaceholder).toHaveBeenCalledWith('mockCid');
+ expect(mockIpfsService.ipfsPin).toHaveBeenCalledWith('application/octet-stream', expect.any(Buffer));
+ });
+});
diff --git a/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.ts b/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.ts
new file mode 100644
index 00000000..cd0952f0
--- /dev/null
+++ b/services/content-watcher/apps/worker/src/request_processor/dsnp.announcement.processor.ts
@@ -0,0 +1,383 @@
+import {
+ ActivityContentTag,
+ ActivityContentAttachment,
+ ActivityContentLink,
+ ActivityContentImageLink,
+ ActivityContentImage,
+ ActivityContentVideoLink,
+ ActivityContentVideo,
+ ActivityContentAudioLink,
+ ActivityContentAudio,
+ ActivityContentProfile,
+} from '@dsnp/activity-content/types';
+import { Injectable, Logger } from '@nestjs/common';
+import { InjectQueue } from '@nestjs/bullmq';
+import { Queue } from 'bullmq';
+import {
+ TagTypeDto,
+ AssetDto,
+ AttachmentTypeDto,
+ IRequestJob,
+ QueueConstants,
+ BroadcastDto,
+ ProfileDto,
+ ReactionDto,
+ ReplyDto,
+ UpdateDto,
+ AnnouncementTypeDto,
+ TombstoneDto,
+ ModifiableAnnouncementTypeDto,
+} from '../../../../libs/common/src';
+import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+import { ConfigService } from '../../../api/src/config/config.service';
+import { calculateDsnpHash } from '../../../../libs/common/src/utils/ipfs';
+import {
+ AnnouncementType,
+ BroadcastAnnouncement,
+ ProfileAnnouncement,
+ ReactionAnnouncement,
+ ReplyAnnouncement,
+ UpdateAnnouncement,
+ createBroadcast,
+ createNote,
+ createProfile,
+ createReaction,
+ createReply,
+ createTombstone,
+ createUpdate,
+} from '../../../../libs/common/src/interfaces/dsnp';
+
+@Injectable()
+export class DsnpAnnouncementProcessor {
+ private logger: Logger;
+
+ constructor(
+ @InjectQueue(QueueConstants.ASSET_QUEUE_NAME) private assetQueue: Queue,
+ @InjectQueue(QueueConstants.BROADCAST_QUEUE_NAME) private broadcastQueue: Queue,
+ @InjectQueue(QueueConstants.REPLY_QUEUE_NAME) private replyQueue: Queue,
+ @InjectQueue(QueueConstants.REACTION_QUEUE_NAME) private reactionQueue: Queue,
+ @InjectQueue(QueueConstants.UPDATE_QUEUE_NAME) private updateQueue: Queue,
+ @InjectQueue(QueueConstants.PROFILE_QUEUE_NAME) private profileQueue: Queue,
+ @InjectQueue(QueueConstants.TOMBSTONE_QUEUE_NAME) private tombstoneQueue: Queue,
+ private configService: ConfigService,
+ private ipfsService: IpfsService,
+ ) {
+ this.logger = new Logger(DsnpAnnouncementProcessor.name);
+ }
+
+ public async collectAnnouncementAndQueue(data: IRequestJob) {
+ this.logger.debug(`Collecting announcement and queuing`);
+ this.logger.verbose(`Processing Activity: ${data.announcementType} for ${data.dsnpUserId}`);
+ try {
+ switch (data.announcementType) {
+ case AnnouncementTypeDto.BROADCAST:
+ await this.queueBroadcast(data);
+ break;
+ case AnnouncementTypeDto.REPLY:
+ await this.queueReply(data);
+ break;
+ case AnnouncementTypeDto.REACTION:
+ await this.queueReaction(data);
+ break;
+ case AnnouncementTypeDto.UPDATE:
+ await this.queueUpdate(data);
+ break;
+ case AnnouncementTypeDto.PROFILE:
+ await this.queueProfile(data);
+ break;
+ case AnnouncementTypeDto.TOMBSTONE:
+ await this.queueTombstone(data);
+ break;
+ default:
+ throw new Error(`Unsupported announcement type ${typeof data.announcementType}`);
+ }
+ } catch (e) {
+ this.logger.error(`Error processing announcement ${data.announcementType} for ${data.dsnpUserId}: ${e}`);
+ throw e;
+ }
+ }
+
+ private async queueBroadcast(data: IRequestJob) {
+ const broadcast = await this.processBroadcast(data.content as BroadcastDto, data.dsnpUserId);
+ await this.broadcastQueue.add(`Broadcast Job - ${data.id}`, broadcast, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async queueReply(data: IRequestJob) {
+ const reply = await this.processReply(data.content as ReplyDto, data.dsnpUserId);
+ await this.replyQueue.add(`Reply Job - ${data.id}`, reply, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async queueReaction(data: IRequestJob) {
+ const reaction = await this.processReaction(data.content as ReactionDto, data.dsnpUserId);
+ await this.reactionQueue.add(`Reaction Job - ${data.id}`, reaction, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async queueUpdate(data: IRequestJob) {
+ const updateDto = data.content as UpdateDto;
+ const updateAnnouncementType: AnnouncementType = await this.getAnnouncementTypeFromModifiableAnnouncementType(updateDto.targetAnnouncementType);
+ const update = await this.processUpdate(updateDto, updateAnnouncementType, updateDto.targetContentHash ?? '', data.dsnpUserId);
+ await this.updateQueue.add(`Update Job - ${data.id}`, update, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async queueProfile(data: IRequestJob) {
+ const profile = await this.processProfile(data.content as ProfileDto, data.dsnpUserId);
+ await this.profileQueue.add(`Profile Job - ${data.id}`, profile, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async queueTombstone(data: IRequestJob) {
+ const tombStoneDto = data.content as TombstoneDto;
+ const announcementType: AnnouncementType = await this.getAnnouncementTypeFromModifiableAnnouncementType(tombStoneDto.targetAnnouncementType);
+ const tombstone = createTombstone(data.dsnpUserId, announcementType, tombStoneDto.targetContentHash ?? '');
+ await this.tombstoneQueue.add(`Tombstone Job - ${data.id}`, tombstone, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 });
+ }
+
+ private async getAnnouncementTypeFromModifiableAnnouncementType(modifiableAnnouncementType: ModifiableAnnouncementTypeDto): Promise {
+ this.logger.debug(`Getting announcement type from modifiable announcement type`);
+ switch (modifiableAnnouncementType) {
+ case ModifiableAnnouncementTypeDto.BROADCAST:
+ return AnnouncementType.Broadcast;
+ case ModifiableAnnouncementTypeDto.REPLY:
+ return AnnouncementType.Reply;
+ default:
+ throw new Error(`Unsupported announcement type ${typeof modifiableAnnouncementType}`);
+ }
+ }
+
+ public async prepareNote(noteContent?: any): Promise<[string, string, string]> {
+ this.logger.debug(`Preparing note`);
+ const tags: ActivityContentTag[] = this.prepareTags(noteContent?.content.tag);
+ const attachments: ActivityContentAttachment[] = await this.prepareAttachments(noteContent?.content.assets);
+
+ const note = createNote(noteContent?.content.content ?? '', new Date(noteContent?.content.published ?? ''), {
+ name: noteContent?.content.name,
+ location: this.prepareLocation(noteContent?.content.location),
+ tag: tags,
+ attachment: attachments,
+ });
+ const noteString = JSON.stringify(note);
+ const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(noteString));
+ const ipfsUrl = await this.formIpfsUrl(cid);
+ return [cid, ipfsUrl, hash];
+ }
+
+ private prepareTags(tagData?: any[]): ActivityContentTag[] {
+ this.logger.debug(`Preparing tags`);
+ const tags: ActivityContentTag[] = [];
+ if (tagData) {
+ tagData.forEach((tag) => {
+ switch (tag.type) {
+ case TagTypeDto.Hashtag:
+ tags.push({ name: tag.name });
+ break;
+ case TagTypeDto.Mention:
+ tags.push({
+ name: tag.name,
+ type: 'Mention',
+ id: tag.mentionedId,
+ });
+ break;
+ default:
+ throw new Error(`Unsupported tag type ${typeof tag.type}`);
+ }
+ });
+ }
+ return tags;
+ }
+
+ private async prepareAttachments(assetData?: any[]): Promise {
+ const attachments: ActivityContentAttachment[] = [];
+ if (assetData) {
+ assetData.forEach(async (asset) => {
+ switch (asset.type) {
+ case AttachmentTypeDto.LINK:
+ attachments.push(this.prepareLinkAttachment(asset));
+ break;
+ case AttachmentTypeDto.IMAGE:
+ attachments.push(await this.prepareImageAttachment(asset));
+ break;
+ case AttachmentTypeDto.VIDEO:
+ attachments.push(await this.prepareVideoAttachment(asset));
+ break;
+ case AttachmentTypeDto.AUDIO:
+ attachments.push(await this.prepareAudioAttachment(asset));
+ break;
+ default:
+ throw new Error(`Unsupported attachment type ${typeof asset.type}`);
+ }
+ });
+ }
+
+ return attachments;
+ }
+
+ private prepareLinkAttachment(asset: AssetDto): ActivityContentLink {
+ this.logger.debug(`Preparing link attachment`);
+ return {
+ type: 'Link',
+ href: asset.href || '',
+ name: asset.name,
+ };
+ }
+
+ private async prepareImageAttachment(asset: AssetDto): Promise {
+ const imageLinks: ActivityContentImageLink[] = [];
+ asset.references?.forEach(async (reference) => {
+ const assetMetaData = await this.assetQueue.getJob(reference.referenceId);
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ const image: ActivityContentImageLink = {
+ mediaType: assetMetaData?.data.mimeType,
+ hash: [hashedContent],
+ height: reference.height,
+ width: reference.width,
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ imageLinks.push(image);
+ });
+
+ return {
+ type: 'Image',
+ name: asset.name,
+ url: imageLinks,
+ };
+ }
+
+ private async prepareVideoAttachment(asset: AssetDto): Promise {
+ const videoLinks: ActivityContentVideoLink[] = [];
+ let duration = '';
+ asset.references?.forEach(async (reference) => {
+ const assetMetaData = await this.assetQueue.getJob(reference.referenceId);
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ const video: ActivityContentVideoLink = {
+ mediaType: assetMetaData?.data.mimeType,
+ hash: [hashedContent],
+ height: reference.height,
+ width: reference.width,
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ duration = duration ?? reference.duration ?? '';
+ videoLinks.push(video);
+ });
+
+ return {
+ type: 'Video',
+ name: asset.name,
+ url: videoLinks,
+ duration,
+ };
+ }
+
+ private async prepareAudioAttachment(asset: AssetDto): Promise {
+ const audioLinks: ActivityContentAudioLink[] = [];
+ let duration = '';
+ asset.references?.forEach(async (reference) => {
+ const assetMetaData = await this.assetQueue.getJob(reference.referenceId);
+ const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ duration = duration ?? reference.duration ?? '';
+ const audio: ActivityContentAudioLink = {
+ mediaType: assetMetaData?.data.mimeType,
+ hash: [hashedContent],
+ type: 'Link',
+ href: await this.formIpfsUrl(reference.referenceId),
+ };
+ audioLinks.push(audio);
+ });
+
+ return {
+ type: 'Audio',
+ name: asset.name,
+ url: audioLinks,
+ duration,
+ };
+ }
+
+ private async processBroadcast(content: BroadcastDto, dsnpUserId: string): Promise {
+ this.logger.debug(`Processing broadcast`);
+ const [cid, ipfsUrl, hash] = await this.prepareNote(content);
+ return createBroadcast(dsnpUserId, ipfsUrl, hash);
+ }
+
+ private async processReply(content: ReplyDto, dsnpUserId: string): Promise {
+ this.logger.debug(`Processing reply for ${content.inReplyTo}`);
+ const [cid, ipfsUrl, hash] = await this.prepareNote(content);
+ return createReply(dsnpUserId, ipfsUrl, hash, content.inReplyTo);
+ }
+
+ private async processReaction(content: ReactionDto, dsnpUserId: string): Promise {
+ this.logger.debug(`Processing reaction ${content.emoji} for ${content.inReplyTo}`);
+ return createReaction(dsnpUserId, content.emoji, content.inReplyTo);
+ }
+
+ private async processUpdate(content: UpdateDto, targetAnnouncementType: AnnouncementType, targetContentHash: string, dsnpUserId: string): Promise {
+ this.logger.debug(`Processing update`);
+ const [cid, ipfsUrl, hash] = await this.prepareNote(content);
+ return createUpdate(dsnpUserId, ipfsUrl, hash, targetAnnouncementType, targetContentHash);
+ }
+
+ private async processProfile(content: ProfileDto, dsnpUserId: string): Promise {
+ this.logger.debug(`Processing profile`);
+ const attachments: ActivityContentImageLink[] = await this.prepareProfileIconAttachments(content.profile.icon ?? []);
+
+ const profileActivity: ActivityContentProfile = {
+ '@context': 'https://www.w3.org/ns/activitystreams',
+ type: 'Profile',
+ name: content.profile.name,
+ published: content.profile.published,
+ location: this.prepareLocation(content.profile.location),
+ summary: content.profile.summary,
+ icon: attachments,
+ tag: this.prepareTags(content.profile.tag),
+ };
+ const profileString = JSON.stringify(profileActivity);
+ const [cid, hash] = await this.pinBufferToIPFS(Buffer.from(profileString));
+ return createProfile(dsnpUserId, await this.formIpfsUrl(cid), hash);
+ }
+
+ private async prepareProfileIconAttachments(icons: any[]): Promise {
+ const attachments: ActivityContentImageLink[] = [];
+ icons.forEach(async (icon) => {
+ const assetMetaData = await this.assetQueue.getJob(icon.referenceId);
+ const contentBuffer = await this.ipfsService.getPinned(icon.referenceId);
+ const hashedContent = await calculateDsnpHash(contentBuffer);
+ const image: ActivityContentImageLink = {
+ mediaType: assetMetaData?.data.mimeType,
+ hash: [hashedContent],
+ height: icon.height,
+ width: icon.width,
+ type: 'Link',
+ href: await this.formIpfsUrl(icon.referenceId),
+ };
+ attachments.push(image);
+ });
+
+ return attachments;
+ }
+
+ private prepareLocation(locationData: any): any {
+ this.logger.debug(`Preparing location`);
+ if (!locationData) return null;
+ return {
+ latitude: locationData.latitude,
+ longitude: locationData.longitude,
+ radius: locationData.radius,
+ altitude: locationData.altitude,
+ accuracy: locationData.accuracy,
+ name: locationData.name,
+ units: locationData.units,
+ type: 'Place',
+ };
+ }
+
+ private async pinBufferToIPFS(buf: Buffer): Promise<[string, string, number]> {
+ const { cid, hash, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
+ return [cid.toString(), hash, size];
+ }
+
+ private async formIpfsUrl(cid: string): Promise {
+ return this.configService.getIpfsCidPlaceholder(cid);
+ }
+}
diff --git a/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts b/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
index e50fdff1..1795abaa 100644
--- a/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
+++ b/services/content-watcher/apps/worker/src/request_processor/request.processor.module.ts
@@ -10,6 +10,7 @@ import { ConfigService } from '../../../api/src/config/config.service';
import { QueueConstants } from '../../../../libs/common/src';
import { RequestProcessorService } from './request.processor.service';
import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+import { DsnpAnnouncementProcessor } from './dsnp.announcement.processor';
@Module({
imports: [
@@ -53,8 +54,26 @@ import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
BullModule.registerQueue({
name: QueueConstants.REQUEST_QUEUE_NAME,
}),
+ BullModule.registerQueue({
+ name: QueueConstants.BROADCAST_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.REPLY_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.REACTION_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.TOMBSTONE_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.UPDATE_QUEUE_NAME,
+ }),
+ BullModule.registerQueue({
+ name: QueueConstants.PROFILE_QUEUE_NAME,
+ }),
],
- providers: [RequestProcessorService, IpfsService],
- exports: [BullModule, RequestProcessorService, IpfsService],
+ providers: [RequestProcessorService, IpfsService, DsnpAnnouncementProcessor],
+ exports: [BullModule, RequestProcessorService, IpfsService, DsnpAnnouncementProcessor],
})
export class RequestProcessorModule {}
diff --git a/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
index 1bf598d0..58c15f2d 100644
--- a/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
+++ b/services/content-watcher/apps/worker/src/request_processor/request.processor.service.ts
@@ -1,11 +1,12 @@
import { InjectRedis } from '@liaoliaots/nestjs-redis';
-import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
+import { Processor, WorkerHost, OnWorkerEvent, InjectQueue } from '@nestjs/bullmq';
import { Injectable, Logger } from '@nestjs/common';
-import { DelayedError, Job } from 'bullmq';
+import { DelayedError, Job, Queue } from 'bullmq';
import Redis from 'ioredis';
import { ConfigService } from '../../../api/src/config/config.service';
import { AnnouncementTypeDto, BroadcastDto, IRequestJob, ProfileDto, QueueConstants, ReplyDto, UpdateDto } from '../../../../libs/common/src';
import { IpfsService } from '../../../../libs/common/src/utils/ipfs.client';
+import { DsnpAnnouncementProcessor } from './dsnp.announcement.processor';
@Injectable()
@Processor(QueueConstants.REQUEST_QUEUE_NAME)
@@ -13,7 +14,8 @@ export class RequestProcessorService extends WorkerHost {
private logger: Logger;
constructor(
- @InjectRedis() private redis: Redis,
+ @InjectRedis() private cacheManager: Redis,
+ private dsnpAnnouncementProcessor: DsnpAnnouncementProcessor,
private configService: ConfigService,
private ipfsService: IpfsService,
) {
@@ -24,15 +26,19 @@ export class RequestProcessorService extends WorkerHost {
async process(job: Job): Promise {
this.logger.log(`Processing job ${job.id} of type ${job.name}`);
this.logger.debug(job.asJSON());
- const assets = this.getAssetReferencesFromRequestJob(job.data);
-
- const pinnedAssets = assets.map((cid) => this.ipfsService.getPinned(cid));
- const pinnedResult = await Promise.all(pinnedAssets);
- // if any of assets does not exists delay the job for a future attempt
- if (pinnedResult.some((buffer) => !buffer)) {
- await this.delayJobAndIncrementAttempts(job);
- } else {
- // TODO: create attachments from assets
+ try {
+ const assets = this.getAssetReferencesFromRequestJob(job.data);
+ const pinnedAssets = assets.map((cid) => this.ipfsService.getPinned(cid));
+ const pinnedResult = await Promise.all(pinnedAssets);
+ // if any of assets does not exists delay the job for a future attempt
+ if (pinnedResult.some((buffer) => !buffer)) {
+ await this.delayJobAndIncrementAttempts(job);
+ } else {
+ await this.dsnpAnnouncementProcessor.collectAnnouncementAndQueue(job.data);
+ }
+ } catch (e) {
+ this.logger.error(e);
+ throw e;
}
}
diff --git a/services/content-watcher/libs/common/src/interfaces/dsnp.ts b/services/content-watcher/libs/common/src/interfaces/dsnp.ts
index 5b0170d8..9f8664ec 100644
--- a/services/content-watcher/libs/common/src/interfaces/dsnp.ts
+++ b/services/content-watcher/libs/common/src/interfaces/dsnp.ts
@@ -18,7 +18,7 @@ export enum AnnouncementType {
type TombstoneFields = {
announcementType: AnnouncementType.Tombstone;
targetAnnouncementType: AnnouncementType;
- targetSignature: string;
+ targetContentHash: string;
};
type BroadcastFields = {
@@ -46,13 +46,20 @@ type ProfileFields = {
url: string;
};
+type UpdateFields = {
+ announcementType: AnnouncementType.Update;
+ targetAnnouncementType: AnnouncementType;
+ targetContentHash: string;
+ url: string;
+};
+
/**
* TypedAnnouncement: an Announcement with a particular AnnouncementType
*/
export type TypedAnnouncement = {
announcementType: T;
fromId: string;
-} & (TombstoneFields | BroadcastFields | ReplyFields | ReactionFields | ProfileFields);
+} & (TombstoneFields | BroadcastFields | ReplyFields | ReactionFields | ProfileFields | UpdateFields);
/**
* Announcement: an Announcement intended for inclusion in a batch file
@@ -84,6 +91,11 @@ export type ReplyAnnouncement = TypedAnnouncement;
*/
export type ReactionAnnouncement = TypedAnnouncement;
+/**
+ * UpdateAnnouncement: an Announcement of type Update
+ */
+export type UpdateAnnouncement = TypedAnnouncement;
+
/**
* createTombstone() generates a tombstone announcement from a given URL and
* hash.
@@ -93,10 +105,10 @@ export type ReactionAnnouncement = TypedAnnouncement;
* @param targetSignature - The signature of the target announcement
* @returns A TombstoneAnnouncement
*/
-export const createTombstone = (fromId: string, targetType: AnnouncementType, targetSignature: string): TombstoneAnnouncement => ({
+export const createTombstone = (fromId: string, targetType: AnnouncementType, targetContentHash: string): TombstoneAnnouncement => ({
announcementType: AnnouncementType.Tombstone,
targetAnnouncementType: targetType,
- targetSignature,
+ targetContentHash,
fromId,
});
@@ -181,3 +193,25 @@ export const createNote = (content: string, published: Date, options?: Partial ({
+ announcementType: AnnouncementType.Update,
+ fromId,
+ targetAnnouncementType: targetType,
+ targetContentHash: targetHash,
+ url,
+});
diff --git a/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts b/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
deleted file mode 100644
index 014c70dd..00000000
--- a/services/content-watcher/libs/common/src/utils/dsnpTypeConverter.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-import { Injectable, Logger } from '@nestjs/common';
-import {
- ActivityContentTag,
- ActivityContentAttachment,
- ActivityContentLink,
- ActivityContentImageLink,
- ActivityContentImage,
- ActivityContentVideoLink,
- ActivityContentVideo,
- ActivityContentAudioLink,
- ActivityContentAudio,
-} from '@dsnp/activity-content/types';
-import { TagTypeDto, AssetDto, AttachmentTypeDto } from '../dtos/activity.dto';
-import { createNote } from '../interfaces/dsnp';
-import { calculateDsnpHash } from './ipfs';
-import { IpfsService } from './ipfs.client';
-import { ConfigService } from '../../../../apps/api/src/config/config.service';
-
-@Injectable()
-export class BatchAnnouncer {
- private logger: Logger;
-
- constructor(
- private configService: ConfigService,
- private ipfsService: IpfsService,
- ) {
- this.logger = new Logger(BatchAnnouncer.name);
- }
-
- public async prepareNote(noteContent?: any): Promise<[string, string, string]> {
- this.logger.debug(`Preparing note`);
- const tags: ActivityContentTag[] = [];
- if (noteContent?.content.tag) {
- noteContent.content.tag.forEach((tag) => {
- switch (tag.type) {
- case TagTypeDto.Hashtag:
- tags.push({ name: tag.name || '' });
- break;
- case TagTypeDto.Mention:
- tags.push({
- name: tag.name || '',
- type: 'Mention',
- id: tag.mentionedId || '',
- });
- break;
- default:
- throw new Error(`Unsupported tag type ${typeof tag.type}`);
- }
- });
- }
-
- const attachments: ActivityContentAttachment[] = [];
- if (noteContent?.content.assets) {
- noteContent.content.assets.forEach(async (asset: AssetDto) => {
- switch (asset.type) {
- case AttachmentTypeDto.LINK: {
- const link: ActivityContentLink = {
- type: 'Link',
- href: asset.href || '',
- name: asset.name || '',
- };
-
- attachments.push(link);
- break;
- }
- case AttachmentTypeDto.IMAGE: {
- const imageLinks: ActivityContentImageLink[] = [];
- asset.references?.forEach(async (reference) => {
- const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
- const hashedContent = await calculateDsnpHash(contentBuffer);
- const image: ActivityContentImageLink = {
- mediaType: 'image', // TODO
- hash: [hashedContent],
- height: reference.height,
- width: reference.width,
- type: 'Link',
- href: await this.formIpfsUrl(reference.referenceId),
- };
- imageLinks.push(image);
- });
- const imageActivity: ActivityContentImage = {
- type: 'Image',
- name: asset.name || '',
- url: imageLinks,
- };
-
- attachments.push(imageActivity);
- break;
- }
- case AttachmentTypeDto.VIDEO: {
- const videoLinks: ActivityContentVideoLink[] = [];
- let duration = '';
- asset.references?.forEach(async (reference) => {
- const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
- const hashedContent = await calculateDsnpHash(contentBuffer);
- const video: ActivityContentVideoLink = {
- mediaType: 'video', // TODO
- hash: [hashedContent],
- height: reference.height,
- width: reference.width,
- type: 'Link',
- href: await this.formIpfsUrl(reference.referenceId),
- };
- duration = reference.duration ?? '';
- videoLinks.push(video);
- });
- const videoActivity: ActivityContentVideo = {
- type: 'Video',
- name: asset.name || '',
- url: videoLinks,
- duration,
- };
-
- attachments.push(videoActivity);
- break;
- }
- case AttachmentTypeDto.AUDIO: {
- const audioLinks: ActivityContentAudioLink[] = [];
- let duration = '';
- asset.references?.forEach(async (reference) => {
- const contentBuffer = await this.ipfsService.getPinned(reference.referenceId);
- const hashedContent = await calculateDsnpHash(contentBuffer);
- duration = reference.duration ?? '';
- const audio: ActivityContentAudioLink = {
- mediaType: 'audio', // TODO
- hash: [hashedContent],
- type: 'Link',
- href: await this.formIpfsUrl(reference.referenceId),
- };
- audioLinks.push(audio);
- });
- const audioActivity: ActivityContentAudio = {
- type: 'Audio',
- name: asset.name || '',
- url: audioLinks,
- duration,
- };
-
- attachments.push(audioActivity);
- break;
- }
- default:
- throw new Error(`Unsupported attachment type ${typeof asset.type}`);
- }
- });
- }
-
- const note = createNote(noteContent?.content.content ?? '', new Date(noteContent?.content.published ?? ''), {
- name: noteContent?.content.name,
- location: {
- latitude: noteContent?.content.location?.latitude,
- longitude: noteContent?.content.location?.longitude,
- radius: noteContent?.content.location?.radius,
- altitude: noteContent?.content.location?.altitude,
- accuracy: noteContent?.content.location?.accuracy,
- name: noteContent?.content.location?.name || '',
- type: 'Place',
- },
- tag: tags,
- attachment: attachments,
- });
- const noteString = JSON.stringify(note);
- const [cid, hash] = await this.pinStringToIPFS(Buffer.from(noteString));
- const ipfsUrl = await this.formIpfsUrl(cid);
- return [cid, hash, ipfsUrl];
- }
-
- private async pinStringToIPFS(buf: Buffer): Promise<[string, string]> {
- const { cid, size } = await this.ipfsService.ipfsPin('application/octet-stream', buf);
- return [cid.toString(), size.toString()];
- }
-
- private async formIpfsUrl(cid: string): Promise {
- return this.configService.getIpfsCidPlaceholder(cid);
- }
-}
From 967e4b2b02394c8410677626ef1655c9f66a446c Mon Sep 17 00:00:00 2001
From: Aramik
Date: Fri, 8 Sep 2023 17:25:55 -0700
Subject: [PATCH 018/137] fixed metadata dependency (#40)
---
.../apps/api/src/api.controller.ts | 16 +-
.../apps/api/src/api.service.ts | 27 ++-
.../dsnp.announcement.processor.spec.ts | 6 +
.../dsnp.announcement.processor.ts | 187 ++++++++++--------
.../request.processor.service.ts | 22 +--
.../libs/common/src/dtos/announcement.dto.ts | 2 +-
.../libs/common/src/dtos/validation.dto.ts | 13 ++
.../src/interfaces/request-job.interface.ts | 1 +
.../libs/common/src/utils/ipfs.client.ts | 2 +-
9 files changed, 160 insertions(+), 116 deletions(-)
diff --git a/services/content-watcher/apps/api/src/api.controller.ts b/services/content-watcher/apps/api/src/api.controller.ts
index c06586b0..05f9b138 100644
--- a/services/content-watcher/apps/api/src/api.controller.ts
+++ b/services/content-watcher/apps/api/src/api.controller.ts
@@ -66,15 +66,15 @@ export class ApiController {
@Post('content/:userDsnpId/broadcast')
@HttpCode(202)
async broadcast(@Param() userDsnpId: DsnpUserIdParam, @Body() broadcastDto: BroadcastDto): Promise {
- await this.apiService.validateAssets(broadcastDto as AssetIncludedRequestDto);
- return this.apiService.enqueueRequest(AnnouncementTypeDto.BROADCAST, userDsnpId.userDsnpId, broadcastDto);
+ const metadata = await this.apiService.validateAssetsAndFetchMetadata(broadcastDto as AssetIncludedRequestDto);
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.BROADCAST, userDsnpId.userDsnpId, broadcastDto, metadata);
}
@Post('content/:userDsnpId/reply')
@HttpCode(202)
async reply(@Param() userDsnpId: DsnpUserIdParam, @Body() replyDto: ReplyDto): Promise {
- await this.apiService.validateAssets(replyDto as AssetIncludedRequestDto);
- return this.apiService.enqueueRequest(AnnouncementTypeDto.REPLY, userDsnpId.userDsnpId, replyDto);
+ const metadata = await this.apiService.validateAssetsAndFetchMetadata(replyDto as AssetIncludedRequestDto);
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.REPLY, userDsnpId.userDsnpId, replyDto, metadata);
}
@Post('content/:userDsnpId/reaction')
@@ -86,8 +86,8 @@ export class ApiController {
@Put('content/:userDsnpId')
@HttpCode(202)
async update(@Param() userDsnpId: DsnpUserIdParam, @Body() updateDto: UpdateDto): Promise {
- await this.apiService.validateAssets(updateDto as AssetIncludedRequestDto);
- return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto);
+ const metadata = await this.apiService.validateAssetsAndFetchMetadata(updateDto as AssetIncludedRequestDto);
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.UPDATE, userDsnpId.userDsnpId, updateDto, metadata);
}
@Delete('content/:userDsnpId')
@@ -99,7 +99,7 @@ export class ApiController {
@Put('profile/:userDsnpId')
@HttpCode(202)
async profile(@Param() userDsnpId: DsnpUserIdParam, @Body() profileDto: ProfileDto): Promise {
- await this.apiService.validateAssets(profileDto as AssetIncludedRequestDto);
- return this.apiService.enqueueRequest(AnnouncementTypeDto.PROFILE, userDsnpId.userDsnpId, profileDto);
+ const metadata = await this.apiService.validateAssetsAndFetchMetadata(profileDto as AssetIncludedRequestDto);
+ return this.apiService.enqueueRequest(AnnouncementTypeDto.PROFILE, userDsnpId.userDsnpId, profileDto, metadata);
}
}
diff --git a/services/content-watcher/apps/api/src/api.service.ts b/services/content-watcher/apps/api/src/api.service.ts
index d985757f..b996be87 100644
--- a/services/content-watcher/apps/api/src/api.service.ts
+++ b/services/content-watcher/apps/api/src/api.service.ts
@@ -16,7 +16,7 @@ import {
RequestTypeDto,
UploadResponseDto,
} from '../../../libs/common/src';
-import { calculateDsnpHash, calculateIpfsCID } from '../../../libs/common/src/utils/ipfs';
+import { calculateIpfsCID } from '../../../libs/common/src/utils/ipfs';
import { IAssetJob, IAssetMetadata } from '../../../libs/common/src/interfaces/asset-job.interface';
import { RedisUtils } from '../../../libs/common/src/utils/redis';
import getAssetDataKey = RedisUtils.getAssetDataKey;
@@ -34,7 +34,12 @@ export class ApiService {
this.logger = new Logger(this.constructor.name);
}
- async enqueueRequest(announcementType: AnnouncementTypeDto, dsnpUserId: string, content?: RequestTypeDto): Promise {
+ async enqueueRequest(
+ announcementType: AnnouncementTypeDto,
+ dsnpUserId: string,
+ content: RequestTypeDto,
+ assetToMimeType?: Map,
+ ): Promise {
const data = {
content,
id: '',
@@ -43,6 +48,10 @@ export class ApiService {
dependencyAttempt: 0,
} as IRequestJob;
data.id = this.calculateJobId(data);
+ if (assetToMimeType) {
+ // not used in id calculation since the order in map might not be deterministic
+ data.assetToMimeType = assetToMimeType;
+ }
const job = await this.requestQueue.add(`Request Job - ${data.id}`, data, { jobId: data.id, removeOnFail: false, removeOnComplete: 2000 }); // TODO: should come from config
this.logger.debug(job);
return {
@@ -50,7 +59,7 @@ export class ApiService {
};
}
- async validateAssets(content: AssetIncludedRequestDto): Promise {
+ async validateAssetsAndFetchMetadata(content: AssetIncludedRequestDto): Promise