diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000..f8de60611e --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# guardian service +OPERATOR_ID="..." +OPERATOR_KEY="..." +SCHEMA_TOPIC_ID="..." + +# IPFSS +NFT_API_KEY="..." \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c84dd268f6..9853ef9579 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,62 +1,56 @@ version: 2 updates: -- package-ecosystem: npm - directory: "/api-docs" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/api-gateway" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/frontend" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/guardian-services" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/interfaces" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/ipfs-client" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/logger-helper" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/logger-service" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/message-broker" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" -- package-ecosystem: npm - directory: "/mrv-sender" - schedule: - interval: weekly - open-pull-requests-limit: 5 - target-branch: "develop" + - package-ecosystem: npm + directory: "/api-docs" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/api-gateway" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/frontend" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/guardian-services" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/interfaces" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/ipfs-client" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/logger-helper" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/logger-service" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" + - package-ecosystem: npm + directory: "/mrv-sender" + schedule: + interval: weekly + open-pull-requests-limit: 5 + target-branch: "develop" diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 2813268d24..92ae14caab 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -5,8 +5,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [ 16.x ] - mongodb-version: [ 4.4 ] + node-version: [16.x] + mongodb-version: [4.4] steps: - uses: actions/checkout@v1 - name: Use Node.js ${{ matrix.node-version }} @@ -23,7 +23,7 @@ jobs: npm install npm run build popd - pushd vc-modules + pushd common npm install npm run build popd diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 686e5c43bb..ef7d272ca6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [ 16.x ] + node-version: [16.x] steps: - uses: actions/checkout@v1 - name: Use Node.js ${{ matrix.node-version }} @@ -18,6 +18,10 @@ jobs: npm install npm run build popd + pushd common + npm install + npm run build + popd pushd logger-helper npm install npm run build @@ -38,10 +42,6 @@ jobs: npm install npm run build popd - pushd message-broker - npm install - npm run build - popd pushd api-gateway npm install npm run build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..3efb5a1c23 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,101 @@ +name: Publish Images +on: + release: + types: [published] + +jobs: + docker: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: get-npm-version + + id: package-version + uses: martinbeentjes/npm-get-version-action@main + with: + path: guardian-service + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - id: 'auth' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v0' + with: + workload_identity_provider: 'projects/101730247931/locations/global/workloadIdentityPools/hedera-registry-pool/providers/hedera-registry-gh-actions' + service_account: 'guardian-publisher@hedera-registry.iam.gserviceaccount.com' + token_format: 'access_token' + + - uses: 'docker/login-action@v1' + with: + registry: 'gcr.io' # or REGION-docker.pkg.dev + username: 'oauth2accesstoken' + password: '${{ steps.auth.outputs.access_token }}' + + - name: logger-service + uses: docker/build-push-action@v2 + with: + context: . + file: ./logger-service/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/logger-service:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/logger-service:latest' + + - name: auth-service + uses: docker/build-push-action@v2 + with: + context: . + file: ./auth-service/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/auth-service:${{ steps.package-version.outputs.current-version}}, gcr.io/hedera-registry/auth-service:latest' + + - name: api-gateway + uses: docker/build-push-action@v2 + with: + context: . + file: ./api-gateway/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/api-gateway:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/api-gateway:latest' + + - name: guardian-service + uses: docker/build-push-action@v2 + with: + context: . + file: ./guardian-service/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/guardian-service:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/guardian-service:latest' + + - name: ipfs-client + uses: docker/build-push-action@v2 + with: + context: . + file: ./ipfs-client/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/ipfs-client:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/ipfs-client:latest' + + - name: topic-viewer + uses: docker/build-push-action@v2 + with: + context: . + file: ./topic-viewer/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/topic-viewer:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/topic-viewer:latest' + + - name: api-docs + uses: docker/build-push-action@v2 + with: + context: . + file: ./api-docs/Dockerfile + push: true + tags: 'gcr.io/hedera-registry/api-docs:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/api-docs:latest' + + - name: web-proxy + uses: docker/build-push-action@v2 + with: + context: . + file: ./web-proxy/Dockerfile.ci + push: true + tags: 'gcr.io/hedera-registry/frontend:${{ steps.package-version.outputs.current-version}} , gcr.io/hedera-registry/frontend:latest' diff --git a/.gitignore b/.gitignore index 39fba9c3ad..0492b71a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,12 +7,10 @@ logger-service/node_modules/ logger-service/dist/ logger-helper/node_modules/ logger-helper/dist/ -message-broker/node_modules/ ui-service/node_modules/ ui-service/dist/ mrv-sender/node_modules/ mrv-sender/dist/ -message-broker/dist/ .vscode/ vc/node_modules/ vc/dist/ @@ -31,3 +29,5 @@ ui-service/.vs/ /guardian-service/config.json /threads-test/node_modules/ api-docs/dist/ +.env +tsconfig.tsbuildinfo diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..2c938431b9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node:16 +WORKDIR /app +EXPOSE 3000 +EXPOSE 3001 +EXPOSE 3002 +EXPOSE 3003 +EXPOSE 3004 +EXPOSE 3005 +EXPOSE 3006 +EXPOSE 4200 +RUN npm install -g nodemon +RUN npm install -g ts-node +CMD ["node", "dev.js"] \ No newline at end of file diff --git a/README.md b/README.md index 7cccdb61e2..e2cc0f760c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To get a local copy up and running, follow these simple example steps. When buil #### Prerequisites * [Docker](https://www.docker.com) (To build with one command) -* [MongoDB](https://www.mongodb.com) and [NodeJS](https://nodejs.org) (If you would like to manually build every component) +* [MongoDB](https://www.mongodb.com), [NodeJS](https://nodejs.org) and [Nats](https://nats.io/) (If you build with docker these components will be installed automatically) * [Hedera Testnet Account](https://portal.hedera.com) * [NFT.Storage Account](https://nft.storage/#getting-started) @@ -77,7 +77,7 @@ To get a local copy up and running, follow these simple example steps. When buil **From the interfaces folder** Build package - ``` + ```sh npm install npm run build ``` @@ -85,7 +85,7 @@ To get a local copy up and running, follow these simple example steps. When buil **From the logger-helper folder** Build package - ``` + ```sh npm install npm run build ``` @@ -93,15 +93,16 @@ To get a local copy up and running, follow these simple example steps. When buil **From the interfaces folder** Build package - ``` + ```sh npm install npm run build ``` - **From the vc-modules folder** + + **From the common folder** Build package - ``` + ```sh npm install npm run build ``` @@ -109,26 +110,11 @@ To get a local copy up and running, follow these simple example steps. When buil **From the logger-helper folder** Build package - ``` + ```sh npm install npm run build ``` - **From the Message broker folder (Need to run first)** - - To build the service: - - ``` - npm install - npm run build - ``` - - To start the service: - - ``` - npm start - ``` - **From the Logger service folder** To build the service: @@ -235,6 +221,18 @@ To get a local copy up and running, follow these simple example steps. When buil ``` ### Note: Once you start the service, please wait for the Initialization Process to be completed. + ### Local development using docker + 1. create .env file at the root level and update all variable requires for docker + ```sh + cp .env.example .env + ``` + 2. Start local development using docker compose + ``` + docker-compose -f docker-compose-dev.yml up --build + + ``` + 3. Access local development using http://localhost:3000 or http://localhost:4200 + ### Troubleshoot **To delete all the Containers** @@ -271,13 +269,6 @@ To run stability tests (certain transactions will be executed 10 times each), th npm run test:stability ``` -To run **message-broker** unit tests, following commands needs to be executed: - -``` -cd message-broker -npm run test -``` - ([back to top](broken-reference)) For complete documentation on following points. Please refer https://docs.hedera.com/guardian diff --git a/api-docs/api/swagger/swagger.yaml b/api-docs/api/swagger/swagger.yaml index 52e200f528..787d8a22a6 100644 --- a/api-docs/api/swagger/swagger.yaml +++ b/api-docs/api/swagger/swagger.yaml @@ -2,7 +2,7 @@ openapi: 3.0.0 info: title: "Guardian" description: "The Guardian is a modular open-source solution that includes best-in-class identity management and decentralized ledger technology (DLT) libraries. At the heart of the Guardian solution is a sophisticated Policy Workflow Engine (PWE) that enables applications to offer a requirements-based tokenization implementation." - version: "2.0.0" + version: "2.1.0" contact: name: "API developer" url: "https://envisionblockchain.com" @@ -1899,7 +1899,7 @@ paths: schema: $ref: '#/components/schemas/PolicyConfig' responses: - 200: + 201: description: Successful operation. 401: description: Unauthorized. @@ -2444,7 +2444,7 @@ paths: schema: $ref: "#/components/schemas/ExternalData" responses: - 201: + 200: description: Successful operation. 500: description: Internal server error. @@ -2540,7 +2540,7 @@ paths: security: - bearerAuth: [] responses: - 200: + 201: description: Successful operation. content: application/json: diff --git a/api-docs/package.json b/api-docs/package.json index 2afd09ba45..8b2b62946e 100644 --- a/api-docs/package.json +++ b/api-docs/package.json @@ -1,10 +1,11 @@ { "name": "api-docs", - "version": "2.0.0", + "version": "2.1.0", "description": "Swagger Documentation", "main": "dist/index.js", "scripts": { "start": "node dist/index.js", + "dev:docker": "nodemon src/index.ts", "build": "tsc" }, "author": "Envision Blockchain Solutions ", diff --git a/api-gateway/Dockerfile b/api-gateway/Dockerfile index a6d3407177..2601cd2d68 100644 --- a/api-gateway/Dockerfile +++ b/api-gateway/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/logger-helper COPY ./logger-helper/package*.json ./ COPY ./logger-helper/tsconfig.json ./ diff --git a/api-gateway/nodemon.json b/api-gateway/nodemon.json new file mode 100644 index 0000000000..8b879fd87b --- /dev/null +++ b/api-gateway/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist", "../logger-helper/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/api-gateway/package-lock.json b/api-gateway/package-lock.json index d896f3c879..0aa94bdfc0 100644 --- a/api-gateway/package-lock.json +++ b/api-gateway/package-lock.json @@ -1,17 +1,17 @@ { "name": "api-gateway", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "api-gateway", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { + "common": "file:../common", "dotenv": "^16.0.0", "express": "^4.17.1", - "fastmq": "^1.3.8", "interfaces": "file:../interfaces", "jszip": "^3.7.1", "logger-helper": "file:../logger-helper", @@ -35,8 +35,23 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" @@ -49,10 +64,10 @@ } }, "../logger-helper": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces" }, "devDependencies": { @@ -193,17 +208,6 @@ "node": ">=4" } }, - "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -592,11 +596,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", @@ -680,14 +679,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -747,18 +738,6 @@ "node": ">=8" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "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", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -915,6 +894,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1165,11 +1148,6 @@ "node": ">=12" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -1504,11 +1482,6 @@ "node": ">= 0.6" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "node_modules/express": { "version": "4.17.3", "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", @@ -1580,27 +1553,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1747,7 +1699,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -1773,19 +1726,6 @@ "node": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -1830,11 +1770,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -1891,6 +1826,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -1907,31 +1843,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -2069,11 +1980,6 @@ "node": ">=10" } }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interfaces": { "resolved": "../interfaces", "link": true @@ -2222,21 +2128,6 @@ "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "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-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2382,11 +2273,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -2565,7 +2451,8 @@ "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", @@ -2783,11 +2670,6 @@ "isarray": "0.0.1" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -3253,11 +3135,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -3390,6 +3267,7 @@ "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -4336,14 +4214,6 @@ } } }, - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -4673,11 +4543,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", @@ -4751,14 +4616,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -4802,15 +4659,6 @@ } } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4923,6 +4771,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5107,11 +4967,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -5371,11 +5226,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "express": { "version": "4.17.3", "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", @@ -5446,24 +5296,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5577,7 +5409,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -5597,16 +5430,6 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -5639,11 +5462,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -5688,6 +5506,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -5698,19 +5517,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -5817,11 +5623,6 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interfaces": { "version": "file:../interfaces", "requires": { @@ -5931,15 +5732,6 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -6064,11 +5856,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -6101,7 +5888,7 @@ "version": "file:../logger-helper", "requires": { "@types/node": "^17.0.13", - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces", "mocha-junit-reporter": "^2.0.2", "tslint": "^6.1.3", @@ -6211,7 +5998,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -6393,11 +6181,6 @@ } } }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -6752,11 +6535,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -6844,7 +6622,8 @@ "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true }, "semver-diff": { "version": "3.1.1", diff --git a/api-gateway/package.json b/api-gateway/package.json index 4e950aef3e..1e41d26c81 100644 --- a/api-gateway/package.json +++ b/api-gateway/package.json @@ -9,12 +9,12 @@ "dependencies": { "dotenv": "^16.0.0", "express": "^4.17.1", - "fastmq": "^1.3.8", "interfaces": "file:../interfaces", "jszip": "^3.7.1", "module-alias": "^2.2.2", "reflect-metadata": "^0.1.13", "logger-helper": "file:../logger-helper", + "common":"file:../common", "ws": "^8.2.1" }, "description": "", @@ -43,10 +43,11 @@ "scripts": { "build": "tsc", "debug": "nodemon dist/index.js", + "dev:docker": "npm run build && nodemon .", "dev": "tsc -w", "lint": "tslint --project .", "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/api-gateway/src/api/service/ipfs.ts b/api-gateway/src/api/service/ipfs.ts index 7291545501..629a1a257e 100644 --- a/api-gateway/src/api/service/ipfs.ts +++ b/api-gateway/src/api/service/ipfs.ts @@ -23,7 +23,7 @@ ipfsAPI.post('/file', async (req: any, res: Response) => { throw new Error("File is not uploaded"); } - res.status(200).json(cid); + res.status(201).json(cid); } catch (error) { new Logger().error(error.message, ['API_GATEWAY']); res.status(500).json({ code: 500, message: error.message }); diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts index 275c5493b6..7b1fd4115a 100644 --- a/api-gateway/src/api/service/policy.ts +++ b/api-gateway/src/api/service/policy.ts @@ -53,7 +53,7 @@ policyAPI.post('/', async (req: AuthenticatedRequest, res: Response) => { const engineService = new PolicyEngine(); try { const policies = await engineService.createPolicy(req.body, req.user) - res.json(policies); + res.status(201).json(policies); } catch (e) { new Logger().error(e.message, ['API_GATEWAY']); res.status(500).send({ code: 500, message: e.message }); @@ -178,6 +178,7 @@ policyAPI.get('/:policyId/export/file', async (req: AuthenticatedRequest, res: R const engineService = new PolicyEngine(); try { const policyFile: any = await engineService.exportFile(req.user, req.params.policyId); + console.log(policyFile) const policy: any = await engineService.getPolicy({ filters: req.params.policyId }); res.setHeader('Content-disposition', `attachment; filename=${policy.name}`); res.setHeader('Content-type', 'application/zip'); @@ -204,7 +205,7 @@ policyAPI.post('/import/message', async (req: AuthenticatedRequest, res: Respons const engineService = new PolicyEngine(); try { const policies = await engineService.importMessage(req.user, req.body.messageId); - res.send(policies); + res.status(201).send(policies); } catch (e) { console.error(e); new Logger().error(e.message, ['API_GATEWAY']); @@ -216,7 +217,7 @@ policyAPI.post('/import/file', async (req: AuthenticatedRequest, res: Response) const engineService = new PolicyEngine(); try { const policies = await engineService.importFile(req.user, req.body); - res.send(policies); + res.status(201).send(policies); } catch (e) { console.error(e); new Logger().error(e.message, ['API_GATEWAY']); diff --git a/api-gateway/src/api/service/schema.ts b/api-gateway/src/api/service/schema.ts index ec47b42c5b..a35f02d468 100644 --- a/api-gateway/src/api/service/schema.ts +++ b/api-gateway/src/api/service/schema.ts @@ -1,6 +1,6 @@ import { Guardians } from '@helpers/guardians'; import { Request, Response, Router } from 'express'; -import { ISchema, SchemaHelper, UserRole } from 'interfaces'; +import { ISchema, UserRole, SchemaHelper } from 'interfaces'; import { AuthenticatedRequest } from '@auth/auth.interface'; import { permissionHelper } from '@auth/authorizationHelper'; import JSZip from "jszip"; @@ -70,7 +70,7 @@ export async function updateSchema(newSchema: ISchema, owner: string): Promise { pageSize = req.query.pageSize; } let owner = user.parent; - if(user.role == UserRole.ROOT_AUTHORITY) { + if (user.role == UserRole.ROOT_AUTHORITY) { owner = user.did; } const { schemes, count } = await guardians.getSchemesByOwner(owner, null, pageIndex, pageSize); @@ -162,7 +162,7 @@ schemaAPI.get('/:topicId', async (req: AuthenticatedRequest, res: Response) => { pageSize = req.query.pageSize; } let owner = user.parent; - if(user.role == UserRole.ROOT_AUTHORITY) { + if (user.role == UserRole.ROOT_AUTHORITY) { owner = user.did; } const { schemes, count } = await guardians.getSchemesByOwner(owner, topicId, pageIndex, pageSize); @@ -323,7 +323,7 @@ schemaAPI.post('/:topicId/import/message', permissionHelper(UserRole.ROOT_AUTHOR const map = await guardians.importSchemesByMessages([messageId], req.user.did, topicId); const { schemes, count } = await guardians.getSchemesByOwner(user.did); SchemaHelper.updatePermission(schemes, user.did); - res.status(200).setHeader('X-Total-Count', count).json(toOld(schemes)); + res.status(201).setHeader('X-Total-Count', count).json(toOld(schemes)); } catch (error) { new Logger().error(error.message, ['API_GATEWAY']); res.status(500).json({ code: 500, message: error.message }); @@ -343,7 +343,7 @@ schemaAPI.post('/:topicId/import/file', permissionHelper(UserRole.ROOT_AUTHORITY const map = await guardians.importSchemesByFile(files, req.user.did, topicId); const { schemes, count } = await guardians.getSchemesByOwner(user.did); SchemaHelper.updatePermission(schemes, user.did); - res.status(200).setHeader('X-Total-Count', count).json(toOld(schemes)); + res.status(201).setHeader('X-Total-Count', count).json(toOld(schemes)); } catch (error) { new Logger().error(error.message, ['API_GATEWAY']); res.status(500).json({ code: 500, message: error.message }); diff --git a/api-gateway/src/api/service/websockets.ts b/api-gateway/src/api/service/websockets.ts index 604c8f97da..5ae7608e8b 100644 --- a/api-gateway/src/api/service/websockets.ts +++ b/api-gateway/src/api/service/websockets.ts @@ -1,19 +1,20 @@ import WebSocket from 'ws'; -import {IncomingMessage, Server} from 'http'; +import { IncomingMessage, Server } from 'http'; import { Users } from '@helpers/users'; import { Logger } from 'logger-helper'; import { MessageAPI } from 'interfaces'; import { IPFS } from '@helpers/ipfs'; import { Guardians } from '@helpers/guardians'; - +import { MessageBrokerChannel, MessageResponse } from 'common'; +import { IUpdateBlockMessage, IErrorBlockMessage } from 'interfaces'; export class WebSocketsService { private wss: WebSocket.Server; constructor( private server: Server, - private channel: any + private channel: MessageBrokerChannel ) { - this.wss = new WebSocket.Server({server}); + this.wss = new WebSocket.Server({ server }); this.registerHeartbeatAnswers(); this.registerAuthorisation(); this.registerMessageHandler(); @@ -58,7 +59,7 @@ export class WebSocketsService { const auth = new Users(); try { const [ - LOGGER_SERVICE, + LOGGER_SERVICE, GUARDIANS_SERVICE, IPFS_CLIENT, AUTH_SERVICE @@ -73,7 +74,7 @@ export class WebSocketsService { { type: MessageAPI.GET_STATUS, data: { - LOGGER_SERVICE: LOGGER_SERVICE, + LOGGER_SERVICE: LOGGER_SERVICE, GUARDIANS_SERVICE: GUARDIANS_SERVICE, IPFS_CLIENT: IPFS_CLIENT, AUTH_SERVICE: AUTH_SERVICE @@ -89,43 +90,45 @@ export class WebSocketsService { }); }); - this.channel.response(MessageAPI.UPDATE_STATUS, async (msg, res) => { + this.channel.response(MessageAPI.UPDATE_STATUS, async (msg) => { this.wss.clients.forEach((client: any) => { try { client.send(JSON.stringify({ type: MessageAPI.UPDATE_STATUS, - data: msg.payload + data: msg })); } catch (e) { console.error('WS Error', e); } }); + return new MessageResponse({}) }); } private registerMessageHandler(): void { - this.channel.response('update-block', async (msg, res) => { + this.channel.response('update-block', async (msg) => { this.wss.clients.forEach((client: any) => { try { client.send(JSON.stringify({ type: 'update-event', - data: msg.payload.uuid + data: msg.uuid })); } catch (e) { console.error('WS Error', e); } }); + return new MessageResponse({}) }); - this.channel.response('block-error', async (msg, res) => { + this.channel.response('block-error', async (msg) => { this.wss.clients.forEach((client: any) => { try { - if (client.user.did === msg.payload.user.did) { + if (client.user.did === msg.user.did) { client.send(JSON.stringify({ type: 'error-event', data: { - blockType: msg.payload.blockType, - message: msg.payload.message + blockType: msg.blockType, + message: msg.message } })); } @@ -134,6 +137,7 @@ export class WebSocketsService { console.error('WS Error', e); } }); + return new MessageResponse({}) }) } } diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index d4a7ee05e2..91d5ec270e 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -8,26 +8,26 @@ import { externalAPI, ipfsAPI } from '@api/service'; -import {Guardians} from '@helpers/guardians'; +import { Guardians } from '@helpers/guardians'; import express from 'express'; -import FastMQ from 'fastmq'; -import {createServer} from 'http'; -import {authorizationHelper} from '@auth/authorizationHelper'; +import { createServer } from 'http'; +import { authorizationHelper } from '@auth/authorizationHelper'; import { IPFS } from '@helpers/ipfs'; -import {policyAPI} from '@api/service/policy'; -import {PolicyEngine} from '@helpers/policyEngine'; -import {WebSocketsService} from '@api/service/websockets'; +import { policyAPI } from '@api/service/policy'; +import { PolicyEngine } from '@helpers/policyEngine'; +import { WebSocketsService } from '@api/service/websockets'; import { Users } from '@helpers/users'; import { Wallet } from '@helpers/wallet'; import { settingsAPI } from '@api/service/settings'; import { loggerAPI } from '@api/service/logger'; import { Logger } from 'logger-helper'; +import { MessageBrokerChannel } from 'common'; const PORT = process.env.PORT || 3002; Promise.all([ - FastMQ.Client.connect(process.env.SERVICE_CHANNEL, 7500, process.env.MQ_ADDRESS) -]).then(async ([channel]) => { + MessageBrokerChannel.connect("API_GATEWAY"), +]).then(async ([cn]) => { const app = express(); app.use(express.json()); app.use(express.raw({ @@ -35,7 +35,7 @@ Promise.all([ limit: '4096kb', type: 'binary/octet-stream' })); - + const channel = new MessageBrokerChannel(cn, 'guardian') new Logger().setChannel(channel); new Guardians().setChannel(channel); new IPFS().setChannel(channel); @@ -44,7 +44,7 @@ Promise.all([ new Wallet().setChannel(channel); const server = createServer(app); - new WebSocketsService(server, channel); + new WebSocketsService(server, new MessageBrokerChannel(cn, 'api-gateway')); //////////////////////////////////////// diff --git a/api-gateway/src/helpers/guardians.ts b/api-gateway/src/helpers/guardians.ts index 195fb6b915..ac8d2cd575 100644 --- a/api-gateway/src/helpers/guardians.ts +++ b/api-gateway/src/helpers/guardians.ts @@ -22,7 +22,7 @@ type IFilter = any; */ @Singleton export class Guardians extends ServiceRequestsBase { - public target: string = 'guardian.*'; + public target: string = 'guardians'; /** * Update settings diff --git a/api-gateway/src/helpers/ipfs.ts b/api-gateway/src/helpers/ipfs.ts index 1839da429d..fc2e24f287 100644 --- a/api-gateway/src/helpers/ipfs.ts +++ b/api-gateway/src/helpers/ipfs.ts @@ -1,4 +1,5 @@ -import { ApplicationStates, CommonSettings, MessageAPI } from "interfaces"; +import { MessageBrokerChannel } from "common"; +import { ApplicationStates, CommonSettings, MessageAPI, IGetFileMessage, IFileResponse, IAddFileMessage } from "interfaces"; import { Singleton } from "./decorators/singleton"; /** @@ -6,21 +7,21 @@ import { Singleton } from "./decorators/singleton"; */ @Singleton export class IPFS { - private channel: any; + private channel: MessageBrokerChannel; private readonly target: string = 'ipfs-client'; /** * Register channel * @param channel */ - public setChannel(channel: any): any { + public setChannel(channel: MessageBrokerChannel): any { this.channel = channel; } /** * Get channel */ - public getChannel(): any { + public getChannel(): MessageBrokerChannel { return this.channel; } @@ -30,15 +31,15 @@ export class IPFS { * * @returns {{ cid: string, url: string }} - hash */ - public async addFile(file: ArrayBuffer): Promise<{ cid: string, url: string }> { - const res = (await this.channel.request(this.target, MessageAPI.IPFS_ADD_FILE, file, 'raw')).payload; + public async addFile(file: ArrayBuffer): Promise { + const res = (await this.channel.request([this.target, MessageAPI.IPFS_ADD_FILE].join('.'), { content: Buffer.from(file).toString('base64') })); if (!res) { throw new Error('Invalid IPFS response'); } if (res.error) { throw new Error(`IPFS: ${res.error}`); } - return res.body; + return res.body } /** @@ -48,7 +49,7 @@ export class IPFS { * @returns File */ public async getFile(cid: string, responseType: 'json' | 'raw' | 'str'): Promise { - const res = (await this.channel.request(this.target, MessageAPI.IPFS_GET_FILE, { cid, responseType }, 'json')).payload; + const res = await this.channel.request([this.target, MessageAPI.IPFS_GET_FILE].join('.'), { cid, responseType }); if (!res) { throw new Error('Invalid IPFS response'); } @@ -64,8 +65,8 @@ export class IPFS { * Update settings * @param settings Settings to update */ - public async updateSettings(settings: CommonSettings): Promise { - const res = (await this.channel.request(this.target, MessageAPI.UPDATE_SETTINGS, settings)).payload; + public async updateSettings(settings: CommonSettings): Promise { + const res = await this.channel.request([this.target, MessageAPI.UPDATE_SETTINGS].join('.'), settings); if (!res) { throw new Error('Invalid IPFS response'); } @@ -78,8 +79,8 @@ export class IPFS { * Get settings * @returns Settings */ - public async getSettings(): Promise { - const res = (await this.channel.request(this.target, MessageAPI.GET_SETTINGS)).payload; + public async getSettings(): Promise { + const res = (await this.channel.request([this.target, MessageAPI.GET_SETTINGS].join('.'), {})); if (!res) { throw new Error('Invalid IPFS response'); } @@ -95,11 +96,11 @@ export class IPFS { * @returns {ApplicationStates} Service state */ public async getStatus(): Promise { - const res = (await this.channel.request(this.target, MessageAPI.GET_STATUS)).payload; - if (!res || res.error) { + const res = await this.channel.request([this.target, MessageAPI.GET_STATUS].join('.'), {}); + if (!res) { return ApplicationStates.STOPPED; } - + return res.body; } } diff --git a/api-gateway/src/helpers/policyEngine.ts b/api-gateway/src/helpers/policyEngine.ts index 41497ab0d6..29926a0496 100644 --- a/api-gateway/src/helpers/policyEngine.ts +++ b/api-gateway/src/helpers/policyEngine.ts @@ -4,7 +4,7 @@ import { ServiceRequestsBase } from '@helpers/serviceRequestsBase'; @Singleton export class PolicyEngine extends ServiceRequestsBase { - public target: string = 'guardian.*' + public target: string = 'guardians' public async getPolicy(filters): Promise { return await this.request(PolicyEngineEvents.GET_POLICY, filters); diff --git a/api-gateway/src/helpers/serviceRequestsBase.ts b/api-gateway/src/helpers/serviceRequestsBase.ts index cfbc410e59..8c7341f917 100644 --- a/api-gateway/src/helpers/serviceRequestsBase.ts +++ b/api-gateway/src/helpers/serviceRequestsBase.ts @@ -1,4 +1,4 @@ -import { IMessageResponse } from 'interfaces'; +import { MessageBrokerChannel, BinaryMessageResponse } from "common"; export class ServiceError extends Error { public code: number; @@ -6,20 +6,20 @@ export class ServiceError extends Error { export abstract class ServiceRequestsBase { abstract readonly target: string; - protected channel: any; + protected channel: MessageBrokerChannel; /** * Register channel * @param channel */ - public setChannel(channel: any): any { + public setChannel(channel: MessageBrokerChannel): any { this.channel = channel; } /** * Get channel */ - public getChannel(): any { + public getChannel(): MessageBrokerChannel { return this.channel; } @@ -29,11 +29,11 @@ export abstract class ServiceRequestsBase { * @param params * @param type */ - public async request(entity: string, params?: any, type?: string): Promise { + public async request(entity: string, params?: any): Promise { try { - const response: IMessageResponse = (await this.channel.request(this.target, entity, params, type)).payload; + const response = await this.channel.request([this.target, entity].join('.'), params); if (!response) { - throw {error: 'Server is not available'}; + throw { error: 'Server is not available' }; } if (response.code !== 200) { throw response; @@ -45,15 +45,20 @@ export abstract class ServiceRequestsBase { throw err } } - - public async rawRequest(entity: string, params?: any, type?: string): Promise { + /** + * Making the request that expect to recieved BinaryMessageResponse + * @param entity + * @param params + * @returns + */ + public async rawRequest(entity: string, params?: any): Promise { try { - const response = (await this.channel.request(this.target, entity, params, type)).payload; + // Binary data will return as base64 string inbody + const response = (await this.channel.request([this.target, entity].join('.'), params,)); if (!response) { throw { error: 'Server is not available' }; } - - return response; + return Buffer.from(response.body, 'base64'); } catch (e) { const err = new ServiceError(`${this.target} (${entity}) send: ` + e.error); err.code = e.code; diff --git a/api-gateway/src/helpers/wallet.ts b/api-gateway/src/helpers/wallet.ts index 56faab743b..796e4ace9c 100644 --- a/api-gateway/src/helpers/wallet.ts +++ b/api-gateway/src/helpers/wallet.ts @@ -1,6 +1,6 @@ -import {Singleton} from '@helpers/decorators/singleton'; +import { Singleton } from '@helpers/decorators/singleton'; import { ServiceRequestsBase } from '@helpers/serviceRequestsBase'; -import { WalletEvents } from 'interfaces'; +import { WalletEvents, IWalletAccount } from 'interfaces'; export enum KeyType { ID = 'ID', @@ -21,7 +21,7 @@ export class Wallet extends ServiceRequestsBase { * @param key */ public async getKey(token: string, type: KeyType, key: string): Promise { - const wallet = await this.request(WalletEvents.GET_KEY, {token, type, key}); + const wallet = await this.request(WalletEvents.GET_KEY, { token, type, key }); return wallet.key; } @@ -33,6 +33,6 @@ export class Wallet extends ServiceRequestsBase { * @param value */ public async setKey(token: string, type: string, key: string, value: string) { - await this.request(WalletEvents.SET_KEY, {token, type, key, value}); + await this.request(WalletEvents.SET_KEY, { token, type, key, value }); } } diff --git a/api-gateway/tsconfig.json b/api-gateway/tsconfig.json index 94b7b82718..df35f17dae 100644 --- a/api-gateway/tsconfig.json +++ b/api-gateway/tsconfig.json @@ -7,6 +7,7 @@ "esModuleInterop": true, "experimentalDecorators": true, "inlineSourceMap": true, + "skipLibCheck": true, "lib": [ "es5", "es6" diff --git a/api-tests/index.js b/api-tests/index.js index fd0589db79..689970e4ae 100644 --- a/api-tests/index.js +++ b/api-tests/index.js @@ -1,26 +1,26 @@ const { spawn } = require('child_process'); -const kill = require('tree-kill'); +const kill = require('tree-kill'); const path = require('path'); const fs = require('fs'); -const {sleep, GenerateTokens} = require("./helpers"); +const { sleep, GenerateTokens } = require("./helpers"); -const {Accounts} = require("./test-suits/accounts"); -const {Profiles} = require("./test-suits/profiles"); -const {Schemas} = require("./test-suits/schemas"); -const {Tokens} = require("./test-suits/tokens"); -const {Trustchains} = require("./test-suits/trustchains"); -const {Policies} = require("./test-suits/policies"); -const {Ipfs} = require("./test-suits/ipfs"); +const { Accounts } = require("./test-suits/accounts"); +const { Profiles } = require("./test-suits/profiles"); +const { Schemas } = require("./test-suits/schemas"); +const { Tokens } = require("./test-suits/tokens"); +const { Trustchains } = require("./test-suits/trustchains"); +const { Policies } = require("./test-suits/policies"); +const { Ipfs } = require("./test-suits/ipfs"); const processes = []; -describe('Tests', async function() { - before(async function() { +describe('Tests', async function () { + before(async function () { const configs = [ - {from: path.resolve(path.join('configs', 'guardian-service', '.env')) , to:path.resolve(path.join('..', 'guardian-service', '.env'))}, - {from: path.resolve(path.join('configs', 'ipfs-client', '.env')) , to:path.resolve(path.join('..', 'ipfs-client', '.env'))}, + { from: path.resolve(path.join('configs', 'guardian-service', '.env')), to: path.resolve(path.join('..', 'guardian-service', '.env')) }, + { from: path.resolve(path.join('configs', 'ipfs-client', '.env')), to: path.resolve(path.join('..', 'ipfs-client', '.env')) }, ] for (let conf of configs) { @@ -29,7 +29,6 @@ describe('Tests', async function() { this.timeout(10000000000); const pathArray = [ - path.resolve(path.join('..', 'message-broker')), path.resolve(path.join('..', 'ipfs-client')), path.resolve(path.join('..', 'guardian-service')), path.resolve(path.join('..', 'ui-service')) @@ -56,7 +55,7 @@ describe('Tests', async function() { Trustchains(); Policies(); - after(async function() { + after(async function () { for (let proc of processes) { kill(proc.pid); } diff --git a/auth-service/Dockerfile b/auth-service/Dockerfile index 7e04142df2..957261d190 100644 --- a/auth-service/Dockerfile +++ b/auth-service/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/logger-helper COPY ./logger-helper/package*.json ./ COPY ./logger-helper/tsconfig.json ./ diff --git a/auth-service/nodemon.json b/auth-service/nodemon.json new file mode 100644 index 0000000000..8b879fd87b --- /dev/null +++ b/auth-service/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist", "../logger-helper/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/auth-service/package-lock.json b/auth-service/package-lock.json index bf8d5659aa..db59db1e55 100644 --- a/auth-service/package-lock.json +++ b/auth-service/package-lock.json @@ -1,16 +1,16 @@ { "name": "auth-service", - "version": "1.0.5", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "auth-service", - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { + "common": "file:../common", "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "interfaces": "file:../interfaces", "jsonwebtoken": "^8.5.1", "logger-helper": "file:../logger-helper", @@ -31,9 +31,27 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", + "dependencies": { + "reflect-metadata": "^0.1.13" + }, "devDependencies": { "@types/node": "^17.0.13", "mocha-junit-reporter": "^2.0.2", @@ -42,10 +60,10 @@ } }, "../logger-helper": { - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces" }, "devDependencies": { @@ -161,17 +179,6 @@ "node": ">=4" } }, - "node_modules/@babel/runtime": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", - "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -356,11 +363,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -449,14 +451,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -508,18 +502,6 @@ "node": ">=8" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -700,6 +682,10 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -881,11 +867,6 @@ "node": ">=12" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -956,32 +937,6 @@ "node": ">=4" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1041,7 +996,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", @@ -1060,19 +1016,6 @@ "node": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -1116,11 +1059,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1188,6 +1126,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -1203,31 +1142,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -1326,11 +1240,6 @@ "node": ">=10" } }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interfaces": { "resolved": "../interfaces", "link": true @@ -1475,21 +1384,6 @@ "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "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-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1627,11 +1521,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -1709,6 +1598,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1781,7 +1671,8 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", @@ -1927,11 +1818,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -2296,11 +2182,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "node_modules/registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -2399,6 +2280,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -3220,7 +3102,8 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yargs": { "version": "16.2.0", @@ -3374,14 +3257,6 @@ } } }, - "@babel/runtime": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", - "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -3522,11 +3397,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -3589,14 +3459,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -3635,15 +3497,6 @@ } } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -3775,6 +3628,18 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3902,11 +3767,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -3958,29 +3818,6 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4021,7 +3858,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -4034,16 +3872,6 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -4085,11 +3913,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -4134,6 +3957,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -4143,19 +3967,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", @@ -4222,16 +4033,12 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interfaces": { "version": "file:../interfaces", "requires": { "@types/node": "^17.0.13", "mocha-junit-reporter": "^2.0.2", + "reflect-metadata": "^0.1.13", "tslint": "^6.1.3", "typescript": "^4.5.5" } @@ -4334,15 +4141,6 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4457,11 +4255,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -4511,7 +4304,7 @@ "version": "file:../logger-helper", "requires": { "@types/node": "^17.0.13", - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces", "mocha-junit-reporter": "^2.0.2", "tslint": "^6.1.3", @@ -4537,6 +4330,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -4593,7 +4387,8 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -4713,11 +4508,6 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -4995,11 +4785,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -5066,6 +4851,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -5622,7 +5408,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yargs": { "version": "16.2.0", diff --git a/auth-service/package.json b/auth-service/package.json index 264880662f..c68280df44 100644 --- a/auth-service/package.json +++ b/auth-service/package.json @@ -7,14 +7,14 @@ "author": "Envision Blockchain Solutions ", "dependencies": { "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "interfaces": "file:../interfaces", "jsonwebtoken": "^8.5.1", "module-alias": "^2.2.2", "mongodb": "^4.2.1", "reflect-metadata": "^0.1.13", "typeorm": "^0.2.41", - "logger-helper": "file:../logger-helper" + "logger-helper": "file:../logger-helper", + "common":"file:../common" }, "description": "", "devDependencies": { @@ -36,6 +36,7 @@ "module": "dist/index.js", "name": "auth-service", "scripts": { + "dev:docker": "nodemon .", "build": "tsc", "debug": "nodemon dist/index.js", "dev": "tsc -w", @@ -43,5 +44,5 @@ "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ui-service.xml" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/auth-service/src/api/accountService.ts b/auth-service/src/api/accountService.ts index c5fd1a4534..c6c31478b3 100644 --- a/auth-service/src/api/accountService.ts +++ b/auth-service/src/api/accountService.ts @@ -1,4 +1,3 @@ -import { AuthEvents, MessageError, MessageResponse, UserRole } from 'interfaces'; import { IAuthUser } from '@api/auth.interface'; import { sign, verify } from 'jsonwebtoken'; import { getMongoRepository } from 'typeorm'; @@ -6,38 +5,55 @@ import { User } from '@entity/user'; import * as util from 'util'; import crypto from 'crypto'; import { Logger } from 'logger-helper'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { + AuthEvents, UserRole, + IGetUserByTokenMessage, + IRegisterNewUserMessage, + IGenerateTokenMessage, + IGenerateTokenResponse, + IGetAllUserResponse, + IRootAuthorityUserResponse, + IGetDemoUserResponse, + IGetUserMessage, + IUpdateUserMessage, + ISaveUserMessage, + IGetUserByIdMessage, + IGetUsersByIdMessage, + IGetUsersByIRoleMessage, + IUser +} from 'interfaces'; export class AccountService { constructor( - private channel + private channel: MessageBrokerChannel ) { this.registerListeners(); } registerListeners(): void { - this.channel.response(AuthEvents.GET_USER_BY_TOKEN, async (msg, res) => { - const { token } = msg.payload; + this.channel.response(AuthEvents.GET_USER_BY_TOKEN, async (msg) => { + const { token } = msg; try { const decryptedToken = await util.promisify(verify)(token, process.env.ACCESS_TOKEN_SECRET, {}); const user = await getMongoRepository(User).findOne({ username: decryptedToken.username }); - res.send(new MessageResponse(user)); + return new MessageResponse(user); } catch (e) { - res.send(new MessageError(e.message)) + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.REGISTER_NEW_USER, async (msg, res) => { + this.channel.response(AuthEvents.REGISTER_NEW_USER, async (msg) => { try { const userRepository = getMongoRepository(User); - const { username, password, role } = msg.payload; + const { username, password, role } = msg; const passwordDigest = crypto.createHash('sha256').update(password).digest('hex'); const checkUserName = await userRepository.count({ username }) > 0; if (checkUserName) { - res.send(new MessageError('An account with the same name already exists.')); - return; + return new MessageError('An account with the same name already exists.'); } const user = userRepository.create({ @@ -47,17 +63,17 @@ export class AccountService { parent: null, did: null }); - res.send(new MessageResponse(await getMongoRepository(User).save(user))); + return new MessageResponse(await getMongoRepository(User).save(user)); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)) + return new MessageError(e.message) } }); - this.channel.response(AuthEvents.GENERATE_NEW_TOKEN, async (msg, res) => { + this.channel.response(AuthEvents.GENERATE_NEW_TOKEN, async (msg) => { try { - const { username, password } = msg.payload; + const { username, password } = msg; const passwordDigest = crypto.createHash('sha256').update(password).digest('hex'); const user = await getMongoRepository(User).findOne({ username }); @@ -67,51 +83,51 @@ export class AccountService { did: user.did, role: user.role }, process.env.ACCESS_TOKEN_SECRET); - res.send(new MessageResponse({ + return new MessageResponse({ username: user.username, did: user.did, role: user.role, accessToken: accessToken - })) + }) } else { - res.send(new MessageError('Bad user')); + return new MessageError('Unauthorized request'); } } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)) + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_ALL_USER_ACCOUNTS, async (msg, res) => { + this.channel.response(AuthEvents.GET_ALL_USER_ACCOUNTS, async (_) => { try { const userAccounts = (await getMongoRepository(User).find({ role: UserRole.USER })).map((e) => ({ username: e.username, parent: e.parent, did: e.did })); - res.send(new MessageResponse(userAccounts)); + return new MessageResponse(userAccounts); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_ALL_ROOT_AUTHORITY_ACCOUNTS, async (msg, res) => { + this.channel.response(AuthEvents.GET_ALL_ROOT_AUTHORITY_ACCOUNTS, async (_) => { try { const userAccounts = (await getMongoRepository(User).find({ role: UserRole.ROOT_AUTHORITY })).map((e) => ({ username: e.username, did: e.did })); - res.send(new MessageResponse(userAccounts)); + return new MessageResponse(userAccounts); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_ALL_USER_ACCOUNTS_DEMO, async (msg, res) => { + this.channel.response(AuthEvents.GET_ALL_USER_ACCOUNTS_DEMO, async (_) => { try { const userAccounts = (await getMongoRepository(User).find()).map((e) => ({ parent: e.parent, @@ -119,80 +135,80 @@ export class AccountService { username: e.username, role: e.role })); - res.send(new MessageResponse(userAccounts)); + return new MessageResponse(userAccounts); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_USER, async (msg, res) => { - const { username } = msg.payload; + this.channel.response(AuthEvents.GET_USER, async (msg) => { + const { username } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).findOne({ username }))); + return new MessageResponse(await getMongoRepository(User).findOne({ username })); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_USER_BY_ID, async (msg, res) => { - const { did } = msg.payload; + this.channel.response(AuthEvents.GET_USER_BY_ID, async (msg) => { + const { did } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).findOne({ did }))); + return new MessageResponse(await getMongoRepository(User).findOne({ did })); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_USERS_BY_ID, async (msg, res) => { - const { dids } = msg.payload; + this.channel.response(AuthEvents.GET_USERS_BY_ID, async (msg) => { + const { dids } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).find({ + return new MessageResponse(await getMongoRepository(User).find({ where: { did: { $in: dids } } - }))); + })); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.GET_USERS_BY_ROLE, async (msg, res) => { - const { role } = msg.payload; + this.channel.response(AuthEvents.GET_USERS_BY_ROLE, async (msg) => { + const { role } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).find({ role }))); + return new MessageResponse(await getMongoRepository(User).find({ role })); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.UPDATE_USER, async (msg, res) => { - const { username, item } = msg.payload; + this.channel.response(AuthEvents.UPDATE_USER, async (msg) => { + const { username, item } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).update({ username }, item))); + return new MessageResponse(await getMongoRepository(User).update({ username }, item)); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); - this.channel.response(AuthEvents.SAVE_USER, async (msg, res) => { - const { user } = msg.payload; + this.channel.response(AuthEvents.SAVE_USER, async (msg) => { + const { user } = msg; try { - res.send(new MessageResponse(await getMongoRepository(User).save(user))); + return new MessageResponse(await getMongoRepository(User).save(user)); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); } diff --git a/auth-service/src/api/walletService.ts b/auth-service/src/api/walletService.ts index 84b7bbcba9..87e6eb7bb0 100644 --- a/auth-service/src/api/walletService.ts +++ b/auth-service/src/api/walletService.ts @@ -1,33 +1,30 @@ -import { AuthEvents, MessageError, MessageResponse, WalletEvents } from 'interfaces'; -import util from 'util'; -import { IAuthUser } from '@api/auth.interface'; -import { verify } from 'jsonwebtoken'; import { getMongoRepository } from 'typeorm'; -import { User } from '@entity/user'; import { WalletAccount } from '@entity/wallet-account'; import { Logger } from 'logger-helper'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { WalletEvents, IGetKeyMessage, ISetKeyMessage } from 'interfaces'; export class WalletService { constructor( - private channel + private channel: MessageBrokerChannel, ) { this.registerListeners(); } registerListeners(): void { - this.channel.response(WalletEvents.GET_KEY, async (msg, res) => { - const {token, type, key} = msg.payload; + this.channel.response(WalletEvents.GET_KEY, async (msg) => { + const { token, type, key } = msg; try { - res.send(new MessageResponse(await getMongoRepository(WalletAccount).findOne({token, type: type + '|' + key}))); + return new MessageResponse(await getMongoRepository(WalletAccount).findOne({ token, type: type + '|' + key })); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)) + return new MessageError(e.message) } }); - this.channel.response(WalletEvents.SET_KEY, async (msg, res) => { - const {token, type, key, value} = msg.payload; + this.channel.response(WalletEvents.SET_KEY, async (msg) => { + const { token, type, key, value } = msg; try { const walletAcc = getMongoRepository(WalletAccount).create({ @@ -35,10 +32,10 @@ export class WalletService { type: type + '|' + key, key: value }); - res.send(new MessageResponse(await getMongoRepository(WalletAccount).save(walletAcc))); + return new MessageResponse(await getMongoRepository(WalletAccount).save(walletAcc)); } catch (e) { new Logger().error(e.toString(), ['AUTH_SERVICE']); - res.send(new MessageError(e.message)) + return new MessageError(e.message) } }); } diff --git a/auth-service/src/app.ts b/auth-service/src/app.ts index 87ea2d97b7..5f9f8047cf 100644 --- a/auth-service/src/app.ts +++ b/auth-service/src/app.ts @@ -1,12 +1,10 @@ -import FastMQ from 'fastmq'; -import {createConnection} from 'typeorm'; +import { createConnection } from 'typeorm'; import { fixtures } from '@helpers/fixtures'; import { AccountService } from '@api/accountService'; import { WalletService } from '@api/walletService'; import { Logger } from 'logger-helper'; -import { ApplicationState, ApplicationStates } from 'interfaces'; - -const PORT = process.env.PORT || 3002; +import { ApplicationState, MessageBrokerChannel } from 'common'; +import { ApplicationStates } from 'interfaces'; Promise.all([ createConnection({ @@ -23,9 +21,10 @@ Promise.all([ entitiesDir: 'dist/entity' } }), - FastMQ.Client.connect(process.env.SERVICE_CHANNEL, 7500, process.env.MQ_ADDRESS) -]).then(async ([db, channel]) => { + MessageBrokerChannel.connect('LOGGER_SERVICE'), +]).then(async ([_, cn]) => { const state = new ApplicationState('AUTH_SERVICE'); + const channel = new MessageBrokerChannel(cn, 'auth-service'); state.setChannel(channel); state.updateState(ApplicationStates.INITIALIZING); await fixtures(); diff --git a/auth-service/src/helpers/fixtures.ts b/auth-service/src/helpers/fixtures.ts index 60f130ec4b..cb713eea24 100644 --- a/auth-service/src/helpers/fixtures.ts +++ b/auth-service/src/helpers/fixtures.ts @@ -14,7 +14,7 @@ export const fixtures = async function (): Promise { role: UserRole.ROOT_AUTHORITY }); let result = await usersRepository.save(user); - console.log(result, crypto.createHash('sha1').update(Math.random().toString()).digest('hex')); + console.log(result); user = usersRepository.create({ username: 'Installer', @@ -23,7 +23,7 @@ export const fixtures = async function (): Promise { role: UserRole.USER }); result = await usersRepository.save(user); - console.log(result, crypto.createHash('sha1').update(Math.random().toString()).digest('hex')); + console.log(result); user = usersRepository.create({ username: 'Installer2', @@ -32,7 +32,7 @@ export const fixtures = async function (): Promise { role: UserRole.USER }); result = await usersRepository.save(user); - console.log(result, crypto.createHash('sha1').update(Math.random().toString()).digest('hex')); + console.log(result); user = usersRepository.create({ username: 'Auditor', @@ -41,6 +41,42 @@ export const fixtures = async function (): Promise { role: UserRole.AUDITOR }); result = await usersRepository.save(user); - console.log(result, crypto.createHash('sha1').update(Math.random().toString()).digest('hex')); + console.log(result); + + user = usersRepository.create({ + username: 'Registrant', + password: crypto.createHash('sha256').update('test').digest('hex'), + walletToken: crypto.createHash('sha1').update(Math.random().toString()).digest('hex'), + role: UserRole.USER + }); + result = await usersRepository.save(user); + console.log(result); + + user = usersRepository.create({ + username: 'VVB', + password: crypto.createHash('sha256').update('test').digest('hex'), + walletToken: crypto.createHash('sha1').update(Math.random().toString()).digest('hex'), + role: UserRole.USER + }); + result = await usersRepository.save(user); + console.log(result); + + user = usersRepository.create({ + username: 'ProjectProponent', + password: crypto.createHash('sha256').update('test').digest('hex'), + walletToken: crypto.createHash('sha1').update(Math.random().toString()).digest('hex'), + role: UserRole.USER + }); + result = await usersRepository.save(user); + console.log(result); + + user = usersRepository.create({ + username: 'Verra', + password: crypto.createHash('sha256').update('test').digest('hex'), + walletToken: crypto.createHash('sha1').update(Math.random().toString()).digest('hex'), + role: UserRole.ROOT_AUTHORITY + }); + result = await usersRepository.save(user); + console.log(result); } } \ No newline at end of file diff --git a/auth-service/tsconfig.json b/auth-service/tsconfig.json index 80cabe3fe5..72d58bcaf4 100644 --- a/auth-service/tsconfig.json +++ b/auth-service/tsconfig.json @@ -8,6 +8,7 @@ "experimentalDecorators": true, "inlineSourceMap": true, "lib": [ + "dom", "es5", "es6" ], diff --git a/message-broker/.gitignore b/common/.gitignore similarity index 100% rename from message-broker/.gitignore rename to common/.gitignore diff --git a/common/package-lock.json b/common/package-lock.json new file mode 100644 index 0000000000..b79f5f77c1 --- /dev/null +++ b/common/package-lock.json @@ -0,0 +1,2730 @@ +{ + "name": "common", + "version": "2.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "common", + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, + "../interfaces": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "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", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "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", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true, + "peer": true + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "peer": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "peer": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "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/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "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/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "peer": true + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "peer": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "peer": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "peer": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "peer": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "peer": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interfaces": { + "resolved": "../interfaces", + "link": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "peer": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.12.0" + } + }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true, + "peer": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "peer": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "peer": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha-junit-reporter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", + "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", + "dev": true, + "dependencies": { + "debug": "^2.2.0", + "md5": "^2.1.0", + "mkdirp": "~0.5.1", + "strip-ansi": "^6.0.1", + "xml": "^1.0.0" + }, + "peerDependencies": { + "mocha": ">=2.2.5" + } + }, + "node_modules/mocha-junit-reporter/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mocha-junit-reporter/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nats": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/nats/-/nats-2.6.1.tgz", + "integrity": "sha512-PwcSZgWS2+JDoiU1Nd25eiV6wdvZbsCrBjyGyhqcJ72+SP2mJw0A0Sz4FKiSehx3mm2A61vwvC9rhkrNAMPpAw==", + "dependencies": { + "nkeys.js": "^1.0.0-9" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/nkeys.js": { + "version": "1.0.0-9", + "resolved": "https://registry.npmjs.org/nkeys.js/-/nkeys.js-1.0.0-9.tgz", + "integrity": "sha512-m9O0NQT+3rUe1om6MWpxV77EuHql/LdorDH+FYQkoeARcM2V0sQ89kM36fArWaHWq/25EmNmQUW0MhLTcbqW1A==", + "dependencies": { + "@types/node": "^14.0.26", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/nkeys.js/node_modules/@types/node": { + "version": "14.18.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.15.tgz", + "integrity": "sha512-hzzmpfqOhsFmvQ9nu87qNQJ8ksofJLBIKkgaYWFapV+W8UGHCxtg5uf69ZtlDSS8rb4ax3lMgpqBnLUQETjCJA==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "peer": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "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==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "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/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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" + } + ], + "peer": true + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "peer": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/tslint/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslint/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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/tslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true, + "peer": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "peer": true, + "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", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "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/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "peer": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true, + "peer": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "peer": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "peer": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "peer": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "peer": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "peer": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "peer": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "peer": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "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 + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "peer": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "peer": true + } + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "peer": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "peer": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "peer": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "peer": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "peer": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "peer": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "peer": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "peer": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true, + "peer": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "peer": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "peer": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "peer": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "peer": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "interfaces": { + "version": "file:../interfaces", + "requires": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "peer": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "peer": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "peer": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "peer": true + }, + "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, + "peer": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true, + "peer": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "peer": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "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, + "peer": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "peer": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + } + }, + "mocha-junit-reporter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", + "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", + "dev": true, + "requires": { + "debug": "^2.2.0", + "md5": "^2.1.0", + "mkdirp": "~0.5.1", + "strip-ansi": "^6.0.1", + "xml": "^1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "peer": true + }, + "nats": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/nats/-/nats-2.6.1.tgz", + "integrity": "sha512-PwcSZgWS2+JDoiU1Nd25eiV6wdvZbsCrBjyGyhqcJ72+SP2mJw0A0Sz4FKiSehx3mm2A61vwvC9rhkrNAMPpAw==", + "requires": { + "nkeys.js": "^1.0.0-9" + } + }, + "nkeys.js": { + "version": "1.0.0-9", + "resolved": "https://registry.npmjs.org/nkeys.js/-/nkeys.js-1.0.0-9.tgz", + "integrity": "sha512-m9O0NQT+3rUe1om6MWpxV77EuHql/LdorDH+FYQkoeARcM2V0sQ89kM36fArWaHWq/25EmNmQUW0MhLTcbqW1A==", + "requires": { + "@types/node": "^14.0.26", + "tweetnacl": "^1.0.3" + }, + "dependencies": { + "@types/node": { + "version": "14.18.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.15.tgz", + "integrity": "sha512-hzzmpfqOhsFmvQ9nu87qNQJ8ksofJLBIKkgaYWFapV+W8UGHCxtg5uf69ZtlDSS8rb4ax3lMgpqBnLUQETjCJA==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "peer": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "peer": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "peer": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "peer": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "peer": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "peer": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "peer": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "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==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "peer": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "peer": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "peer": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "peer": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "peer": true + }, + "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, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "peer": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "peer": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true, + "peer": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "peer": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "peer": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "peer": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "peer": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "peer": true + } + } +} diff --git a/common/package.json b/common/package.json new file mode 100644 index 0000000000..78eb6f71a7 --- /dev/null +++ b/common/package.json @@ -0,0 +1,29 @@ +{ + "author": "Envision Blockchain Solutions ", + "description": "Common package share cross all services", + "dependencies": { + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "interfaces": "file:../interfaces" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + }, + "files": [ + "dist" + ], + "license": "Apache-2.0", + "main": "dist/index.js", + "module": "dist/index.js", + "name": "common", + "scripts": { + "build": "tsc", + "dev": "tsc -w", + "lint": "tslint --project .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "version": "2.1.0" +} diff --git a/interfaces/src/decorators/singleton.ts b/common/src/decorators/singleton.ts similarity index 100% rename from interfaces/src/decorators/singleton.ts rename to common/src/decorators/singleton.ts diff --git a/interfaces/src/helpers/application-state.ts b/common/src/helpers/application-state.ts similarity index 53% rename from interfaces/src/helpers/application-state.ts rename to common/src/helpers/application-state.ts index 587c832c8d..d4125da213 100644 --- a/interfaces/src/helpers/application-state.ts +++ b/common/src/helpers/application-state.ts @@ -1,35 +1,34 @@ import { Singleton } from "../decorators/singleton"; -import { IMessageResponse, MessageError, MessageResponse } from "../models/message-response"; -import { ApplicationStates } from "../type/application-states.type"; -import { MessageAPI } from "../type/message-api.type"; +import { MessageBrokerChannel } from "../mq"; +import { ApplicationStates, MessageAPI } from "interfaces"; +import { MessageResponse, MessageError } from "../models/message-response"; @Singleton export class ApplicationState { - private channel: any; + private channel: MessageBrokerChannel; private state: ApplicationStates; - private readonly target: string = "api-gateway"; private serviceName: string; /** * Register channel - * @param channel + * @param channel: MessageBrokerChannel */ - public setChannel(channel: any): any { + public setChannel(channel: MessageBrokerChannel): any { this.channel = channel; - this.channel.response(MessageAPI.GET_STATUS, async (msg, res) => { + this.channel.response(MessageAPI.GET_STATUS, async () => { try { - res.send(new MessageResponse(this.state)); + return new MessageResponse(this.state); } catch (e) { - res.send(new MessageError(e)); + return new MessageError(e); } }); } - + /** * Get channel */ - public getChannel(): any { + public getChannel(): MessageBrokerChannel { return this.channel; } @@ -46,7 +45,7 @@ export class ApplicationState { if (this.serviceName) { const res = {}; res[this.serviceName] = state; - this.channel.request(this.target, MessageAPI.UPDATE_STATUS, res, 'json'); + this.channel.request([this.channel.channelName, MessageAPI.UPDATE_STATUS].join('.'), res); } } } diff --git a/common/src/index.ts b/common/src/index.ts new file mode 100644 index 0000000000..c52dc904b6 --- /dev/null +++ b/common/src/index.ts @@ -0,0 +1,5 @@ +import 'reflect-metadata'; +export * from './models/message-response'; +export * from './decorators/singleton'; +export * from './helpers/application-state'; +export * from './mq'; diff --git a/interfaces/src/models/message-response.ts b/common/src/models/message-response.ts similarity index 79% rename from interfaces/src/models/message-response.ts rename to common/src/models/message-response.ts index 9240d1dbcb..b8c2ca6c07 100644 --- a/interfaces/src/models/message-response.ts +++ b/common/src/models/message-response.ts @@ -16,6 +16,18 @@ export class MessageResponse implements IMessageResponse { } } +export class BinaryMessageResponse implements IMessageResponse { + public readonly code: number; + public readonly body: string; + public readonly error: string; + + constructor(body: ArrayBuffer, code: number = 200) { + this.code = code; + this.body = Buffer.from(body).toString("base64"); + this.error = null; + } +} + export class MessageError implements IMessageResponse, Error { public readonly body: T; public readonly error: string; @@ -27,7 +39,7 @@ export class MessageError implements IMessageResponse, Error { this.code = code; this.body = null; this.error = error; - + this.name = error; this.message = error; } @@ -50,10 +62,10 @@ export function Response() { let oldFunc = descriptor.value; descriptor.value = async function () { const response: IMessageResponse = await oldFunc.apply(this, arguments); - if (response.code === 0) { + if (response.code === 0) { throw new Error('Initialization'); } - if (response.error) { + if (response.error) { throw response.error; } return response.body; diff --git a/common/src/mq/index.ts b/common/src/mq/index.ts new file mode 100644 index 0000000000..0eb22e993d --- /dev/null +++ b/common/src/mq/index.ts @@ -0,0 +1,92 @@ +import assert from 'assert'; +import { JSONCodec, Subscription, NatsConnection, StringCodec, connect } from 'nats'; +import { IMessageResponse, MessageError } from '../models/message-response'; + +const MQ_TIMEOUT = +process.env.MQ_TIMEOUT || 300000; + +export class MessageBrokerChannel { + constructor(private channel: NatsConnection, public channelName: string) { } + + private getTarget(eventType: string) { + if (eventType.includes(this.channelName) || eventType.includes('*')) { + return eventType; + } + return `${this.channelName}.${eventType}`; + } + /** + * Subscribe to the MQ event + * @param eventType : target event type @example ipfs-clients.get-file + * @param handleFunc: the call back function to process the request + */ + public async response(eventType: string, handleFunc: (data: TData) => Promise>) { + const target = this.getTarget(eventType); + console.log('MQ subscribed: %s', target); + const sub = this.channel.subscribe(target); + const sc = JSONCodec<{ payload: TData }>(); + const responseSc = JSONCodec>(); + (async (sub: Subscription) => { + for await (const m of sub) { + console.log('MQ response start: %s', m.subject); + const data = sc.decode(m.data); + let responseMessage: IMessageResponse; + try { + responseMessage = await handleFunc(data.payload || data as any); + } catch (err) { + responseMessage = new MessageError(err.message, err.code); + } + m.respond(responseSc.encode(responseMessage)); + console.log('MQ response end: ', m.subject); + } + })(sub); + } + /** + * sending the request to the MQ and waiting for response + * @param eventType target subscription , it should follow the pattern: target subscription . event type (ex : ipfs-clients.get-file) + * @param payload input data for event + * @param timeout timeout in milliseconds, this will overwrite default env var MQ_TIMEOUT varlue @default 30000 + * @returns MessageResponse or Error response + */ + public async request(eventType: string, payload: T, timeout?: number): Promise> { + try { + const target = eventType; + console.log('MQ request: %s', target); + + const sc = payload && typeof payload === 'string' ? StringCodec() : JSONCodec(); + const msg = await this.channel.request(eventType, sc.encode((payload as any) || {}), { + timeout: timeout || MQ_TIMEOUT, + }); + + const responseSc = JSONCodec>(); + return responseSc.decode(msg.data); + } catch (e) { + // Nats no subscribe error + if (e.code === '503') { + console.warn('No listener for message event type = %s', eventType); + return; + } + console.error(e.message, e.stack, e); + throw e; + } + } + + public publish(eventType: string, data: string) { + const target = this.getTarget(eventType); + console.log('MQ publish: %s', target); + const sc = StringCodec(); + this.channel.publish(target, sc.encode(data)); + } + /** + * Create the Nats MQ connection + * @param connectionName + * @returns + */ + public static async connect(connectionName: string) { + assert(process.env.MQ_ADDRESS, 'Missing MQ_ADDRESS environment variable'); + return connect({ + servers: [process.env.MQ_ADDRESS], + name: connectionName, + reconnectDelayHandler: () => 2000, + maxReconnectAttempts: -1 // reconnect forever + }); + }; +} \ No newline at end of file diff --git a/message-broker/tsconfig.json b/common/tsconfig.json similarity index 84% rename from message-broker/tsconfig.json rename to common/tsconfig.json index 3db81a7fc7..a10534fb71 100644 --- a/message-broker/tsconfig.json +++ b/common/tsconfig.json @@ -3,6 +3,7 @@ "module": "commonjs", "target": "es6", "lib": [ + "dom", "es5", "es6" ], @@ -11,7 +12,8 @@ "outDir": "dist/", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "esModuleInterop": true + "esModuleInterop": true, + "declaration": true }, "include": [ "src/**/*" diff --git a/common/tslint.json b/common/tslint.json new file mode 100644 index 0000000000..bf191dc1c7 --- /dev/null +++ b/common/tslint.json @@ -0,0 +1,31 @@ +{ + "extends": "tslint:recommended", + "rules": { + "max-line-length": { + "options": [360] + }, + "new-parens": true, + "no-arg": true, + "no-bitwise": false, + "no-conditional-assignment": true, + "no-consecutive-blank-lines": false, + "only-arrow-functions": false, + "no-empty": false, + "no-console": false, + "triple-equals": false, + "prefer-for-of": false, + "max-classes-per-file": false, + "no-shadowed-variable": false, + "prefer-const": false, + "object-literal-shorthand": false, + "no-var-keyword": false, + "one-variable-per-declaration": false, + "no-trailing-whitespace": false, + "unified-signatures": false + }, + "jsRules": { + "max-line-length": { + "options": [120] + } + } +} diff --git a/dev.js b/dev.js new file mode 100644 index 0000000000..c0aecd596f --- /dev/null +++ b/dev.js @@ -0,0 +1,47 @@ +const execSync = require('child_process').execSync; +const spaw = require('child_process').spawn; +const fs = require('fs'); + +(async () => { + const buildAndWatch = async (folder, skipWatch = false) => { + const log = (message) => console.log(`${folder}: ${message}`); + + await execSync(`npm install --prefix ${folder}`, { stdio: 'inherit', shell: true }); + + if (skipWatch) { + log('skip watch project') + return; + } + + if (!fs.existsSync(folder + '/dist/')) { + await execSync(`npm run build --prefix ${folder}`, { stdio: 'inherit', shell: true }); + } + + await new Promise((resolve) => { + log('Watching changes...'); + const child = spaw('npm', ['run', 'dev', '--prefix', folder], { shell: true }); + + child.stdout.on('data', log); + child.stderr.on('data', log); + + child.on('close', (code) => { + resolve(code) + }); + }); + + } + console.log('Building and watching...'); + await Promise.all([ + "interfaces", + "common", + "logger-helper", + "logger-service", + "frontend", + "auth-service", + "guardian-service", + "api-gateway", + "mrv-sender", + "ipfs-client", + "topic-viewer" + ].map(project => buildAndWatch(project, project === "frontend"))); +})(); \ No newline at end of file diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000000..45443f94ba --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,192 @@ +version: '3.8' +services: + mongo: + image: mongo + restart: always + expose: + - 27017 + ports: + - 27017:27017 + message-broker: + image: nats + expose: + - 4222 + ports: + - '8222:8222' + - '4222:4222' + - '6222:6222' + command: '--http_port 8222' + dev-tools: + build: . + image: guardian-development + volumes: + - ./:/app + - ~/.npm/:/root/.npm + restart: on-failure + command: 'node dev.js' + + api-docs: + image: guardian-development + volumes: + - ./:/app + expose: + - 3001 + ports: + - 3001:3001 + depends_on: + - dev-tools + command: npm run dev:docker --prefix /app/api-docs + logger-service: + image: guardian-development + depends_on: + - dev-tools + - message-broker + volumes: + - ./:/app + restart: always + command: npm run dev:docker --prefix /app/logger-service + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + + auth-service: + image: guardian-development + restart: always + depends_on: + - dev-tools + - mongo + - message-broker + - logger-service + + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + volumes: + - ./:/app + command: npm run dev:docker --prefix /app/auth-service + + api-gateway: + image: guardian-development + restart: always + expose: + - 3002 + ports: + - 3002:3002 + depends_on: + - dev-tools + - mongo + - message-broker + - guardian-service + - auth-service + - logger-service + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + volumes: + - ./:/app + command: npm run dev:docker --prefix /app/api-gateway + + topic-viewer: + image: guardian-development + restart: always + expose: + - 3006 + ports: + - 3006:3006 + depends_on: + - dev-tools + - mongo + - message-broker + - guardian-service + - auth-service + - logger-service + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + volumes: + - ./:/app + command: npm run dev:docker --prefix /app/topic-viewer + + guardian-service: + image: guardian-development + restart: always + depends_on: + - mongo + - message-broker + - auth-service + - logger-service + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + - OPERATOR_ID=${OPERATOR_ID} + - OPERATOR_KEY=${OPERATOR_KEY} + - SCHEMA_TOPIC_ID=${SCHEMA_TOPIC_ID} + volumes: + - ./:/app + command: npm run dev:docker --prefix /app/guardian-service + + ipfs-client: + image: guardian-development + restart: always + ports: + - '5001:5001' + - '5002:5002' + - '4001:4001' + - '4002:4002' + - '8080:8080' + - '8081:8081' + depends_on: + - dev-tools + - message-broker + - logger-service + volumes: + - ./:/app + environment: + - MQ_ADDRESS=message-broker + - DB_HOST=mongo + - NFT_API_KEY=${NFT_API_KEY} + command: npm run dev:docker --prefix /app/ipfs-client + + mrv-sender: + image: guardian-development + expose: + - 3005 + depends_on: + - dev-tools + volumes: + - ./:/app + command: npm run dev:docker --prefix /app/mrv-sender + front-end: + image: guardian-development + expose: + - 4200 + ports: + - 4200:4200 + depends_on: + - dev-tools + volumes: + - ./:/app + environment: + - NG_PERSISTENT_BUILD_CACHE=1 + - CI=local + command: npm run dev:docker --prefix /app/frontend + + web-proxy: + image: nginx + ports: + - '3000:80' + depends_on: + - guardian-service + - auth-service + - api-gateway + - api-docs + - mrv-sender + - front-end + volumes: + - ./web-proxy/configs/local.conf:/etc/nginx/conf.d/default.conf +volumes: + mongo: + # volume-guardian-service: + # volume-ui-service: + # volume-mrv-sender: + # volume-message-broker: diff --git a/docker-compose.yml b/docker-compose.yml index 0e6ce50bb0..b742d5c591 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,12 +14,12 @@ services: - 3001 message-broker: - build: - context: . - dockerfile: ./message-broker/Dockerfile + image: nats expose: - - 7500 - - 3003 + - 4222 + ports: + - '8222:8222' + command: '--http_port 8222' logger-service: build: @@ -103,7 +103,7 @@ services: - mrv-sender volumes: mongo: - # volume-guardian-service: - # volume-ui-service: - # volume-mrv-sender: -# volume-message-broker: + # volume-guardian-service: + # volume-ui-service: + # volume-mrv-sender: + # volume-message-broker: diff --git a/docs/.gitbook/assets/Guardian_Architecture_Diagram.png b/docs/.gitbook/assets/Guardian_Architecture_Diagram.png new file mode 100644 index 0000000000..b48fde753c Binary files /dev/null and b/docs/.gitbook/assets/Guardian_Architecture_Diagram.png differ diff --git a/docs/.gitbook/assets/PW_26 (1) (1) (1).png b/docs/.gitbook/assets/PW_26 (1) (1) (1).png new file mode 100644 index 0000000000..e544e8a7b2 Binary files /dev/null and b/docs/.gitbook/assets/PW_26 (1) (1) (1).png differ diff --git a/docs/.gitbook/assets/PW_26 (1) (1).png b/docs/.gitbook/assets/PW_26 (1) (1).png new file mode 100644 index 0000000000..e544e8a7b2 Binary files /dev/null and b/docs/.gitbook/assets/PW_26 (1) (1).png differ diff --git a/docs/.gitbook/assets/Verra_2 (1) (1).png b/docs/.gitbook/assets/Verra_2 (1) (1).png new file mode 100644 index 0000000000..380b9ce5c4 Binary files /dev/null and b/docs/.gitbook/assets/Verra_2 (1) (1).png differ diff --git a/docs/.gitbook/assets/Verra_2 (1).png b/docs/.gitbook/assets/Verra_2 (1).png new file mode 100644 index 0000000000..380b9ce5c4 Binary files /dev/null and b/docs/.gitbook/assets/Verra_2 (1).png differ diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 390989e20c..4633d7fd35 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -22,7 +22,8 @@ * [Demo Usage Guide](demo-guide/demo-usage-guide.md) * [Demo Using APIs](demo-guide/demo-using-apis.md) * [Verra Redd+ Demo Guide](demo-guide/verra-redd+-demo-guide.md) -* [iREC Demo Guide](demo-guide/irec-demo-guide.md) +* [iREC Demo UI Guide](demo-guide/irec-demo-guide.md) +* [iREC 2 API Demo Guide](demo-guide/api-workflow-of-irec-demo.md) ## Versioning and Deprecation Policy @@ -59,8 +60,10 @@ * [retirementDocumentBlock](available-policy-workflow-blocks/retirementdocumentblock.md) * [wipeDocumentBlock](available-policy-workflow-blocks/token-wipe-workflow-block.md) * [calculateContainerBlock & calculateMathAddOnBlock](available-policy-workflow-blocks/calculatecontainerblock-and-calculatemathaddonblock.md) -* [aggregateDocumentBlock](available-policy-workflow-blocks/aggregate-data-workflow-block.md) * [reportBlock & reportItemBlock](available-policy-workflow-blocks/reportblock-and-reportitemblock.md) +* [switchBlock](available-policy-workflow-blocks/switchblock.md) +* [aggregateDocumentBlock](available-policy-workflow-blocks/aggregatedocumentblock.md) +* [TimerBlock](available-policy-workflow-blocks/timerblock.md) ## Policy Workflow Creation using the Guardian User Interface @@ -169,3 +172,7 @@ * [Returning Logs](logs-apis/returning-logs.md) * [Returning Log Attributes](logs-apis/returning-log-attributes.md) + +## External APIs + +* [Sends Data from External Source](external-apis/sends-data-from-external-source.md) diff --git a/docs/available-policy-workflow-blocks/action-workflow-block.md b/docs/available-policy-workflow-blocks/action-workflow-block.md index fe9659aef1..45509b22ef 100644 --- a/docs/available-policy-workflow-blocks/action-workflow-block.md +++ b/docs/available-policy-workflow-blocks/action-workflow-block.md @@ -4,13 +4,13 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -| Type | A block to create custom actions. | **InterfaceAction**Block (Can't be changed). | -| Tag | Unique name for the logic block. | download\_config\_btn. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | -| Type | Specific the type of action workflow action block. | Current options are: SELECTOR (select an action) and DOWNLOAD (download files) | +| type | A block to create custom actions. | **InterfaceAction**Block (Can't be changed). | +| tag | Unique name for the logic block. | download\_config\_btn. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| type | Specific the type of action workflow action block. | Current options are: SELECTOR (select an action) and DOWNLOAD (download files) | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/aggregate-data-workflow-block.md b/docs/available-policy-workflow-blocks/aggregate-data-workflow-block.md deleted file mode 100644 index 85cd9b5fe5..0000000000 --- a/docs/available-policy-workflow-blocks/aggregate-data-workflow-block.md +++ /dev/null @@ -1,19 +0,0 @@ -# aggregateDocumentBlock - -### Properties - -| Block Property | Definition | Example Input | -| ---------------- | --------------------------------------------------------------------------------- | ------------------------------------------------ | -| Type | Type of workflow logic block. | **aggregateDocument**Block (Can't be changed). | -| Tag | Unique name for the logic block. | example\_tag\_relevant\_to\_the\_workkflow step. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | - -### UI Properties - -| UI Property | Definition | -| ----------- | ----------------------------- | -| Rule | Enter the rule. | -| threshold | Enter threshold calculations. | diff --git a/docs/available-policy-workflow-blocks/aggregatedocumentblock.md b/docs/available-policy-workflow-blocks/aggregatedocumentblock.md new file mode 100644 index 0000000000..dc79bbdc31 --- /dev/null +++ b/docs/available-policy-workflow-blocks/aggregatedocumentblock.md @@ -0,0 +1,39 @@ +# aggregateDocumentBlock + +### Properties + +Input - a document or an array of documents which will be aggregated + +Output - an array of documents, after the reporting period expired or the condition is met + +| Block Property | Definition | Example Input | +| ---------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| tag | Unique name for the logic block. | aggregateDocumentBlock | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| On errors | Called if the system error has occurs in the Block |

  • No action
  • Retry
  • Go to step
  • Go to tag
| +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| AggregateType | Type of Aggregate |

  • Cumulative Dimension
  • Period
| + +``` +If ‘Aggregate Type’ = ‘Cumulative Dimension’ + Expressions - calculated variables which help to ease the work with Condition and enable complex calculations + Expression (i) + Variable Name (string) - name of the the variable + Variable Value (string) - formula for calculating of the value of the variable + Condition (string) - condition expression which can contain math formulas + +If ‘Aggregate Type’ = ‘Period’ + Timer - timer object to track the aggregation period (launched separately) + (Please note that this functionality will change in the near future) + + Empty Data - if this parameter is set to true the timer gets triggered even if there were no data +``` + +### UI Properties + +| UI Property | Definition | Status | +| ----------- | ---------------------------- | ------------------------------------------ | +| Rule | Type of Rule | Deprecated | +| Threshold | Enter threshold calculations | Deprecated | diff --git a/docs/available-policy-workflow-blocks/container-workflow-block.md b/docs/available-policy-workflow-blocks/container-workflow-block.md index 69e6b1372d..6b670c7d55 100644 --- a/docs/available-policy-workflow-blocks/container-workflow-block.md +++ b/docs/available-policy-workflow-blocks/container-workflow-block.md @@ -4,11 +4,11 @@ | Block Property | Definition | Example Input | | -------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | A block which contains and organizes other blocks. | **InterfaceContainer**Block (Can't be changed). | -| Tag | Unique name for the logic block. | installer\_header. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the apprioriate block from the dropdown. | +| type | A block which contains and organizes other blocks. | **InterfaceContainer**Block (Can't be changed). | +| tag | Unique name for the logic block. | installer\_header. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the apprioriate block from the dropdown. | ### **UI Properties** @@ -20,8 +20,6 @@ ### API Parameters - - {% swagger method="get" path=" 'InterfaceContainerBlock'" baseUrl="blocktype :" summary="" %} {% swagger-description %} diff --git a/docs/available-policy-workflow-blocks/documentssourceaddonblock.md b/docs/available-policy-workflow-blocks/documentssourceaddonblock.md index 303ac2fba3..15dd113696 100644 --- a/docs/available-policy-workflow-blocks/documentssourceaddonblock.md +++ b/docs/available-policy-workflow-blocks/documentssourceaddonblock.md @@ -1,4 +1,4 @@ -# DocumentsSourceAddOnBlock +# DocumentsSourceAddOn {% hint style="info" %} Note: This block is used for dropdown. You can add multiple blocks to 1 grid to combine different data. @@ -6,17 +6,17 @@ Note: This block is used for dropdown. You can add multiple blocks to 1 grid to ### Properties -| Block Property | Definition | Example Input | -| --------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -| Type | A block for searching VC, for grid | **DocumentsSourceAddOn** Block (Can't be changed). | -| Tag | Unique name for the logic block. | approve_d\_documents\__grid\_source | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | -| Data Type | Specify the table to request the data from. | Current options are: Verifiable Credential, DID, Approve, or Hedera. | -| Schema | Filters the VC according to the selected scheme | iRec Application Details (1.0.0) PUBLISHED | -| Only Own Documents | When checked, filter out only VCs created by the user | checked or unchecked | -| Only Assign Documents | When checked, it filter only VCs assigned to the user | checked or unchecked | +| Block Property | Definition | Example Input | +| ------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | +| type | A block for searching VC, for grid | **DocumentsSourceAddOn** Block (Can't be changed). | +| tag | Unique name for the logic block. | approve_d\_documents\__grid\_source | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | +| dataType | Specify the table to request the data from. | Current options are: Verifiable Credential, DID, Approve, or Hedera. | +| schema | Filters the VC according to the selected scheme | iRec Application Details (1.0.0) PUBLISHED | +| onlyOwnDocuments | When checked, filter out only VCs created by the user | checked or unchecked | +| onlyAssignDocuments | When checked, it filter only VCs assigned to the user | checked or unchecked | ### Filter Properties diff --git a/docs/available-policy-workflow-blocks/external-data-workflow-block.md b/docs/available-policy-workflow-blocks/external-data-workflow-block.md index b4158300bd..ff9d58d3bc 100644 --- a/docs/available-policy-workflow-blocks/external-data-workflow-block.md +++ b/docs/available-policy-workflow-blocks/external-data-workflow-block.md @@ -4,10 +4,11 @@ | Block Property | Definition | Example Input | | -------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | -| Type | Receives data from the external source and passes them over the the next block. | **externalData**Block (Can't be changed). | -| Tag | Unique name for the logic block. | mrv\_source. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Entity Type | Specify the type of Entity this workflow block is for. | MRV. | -| Schema | Pre-configured schemas relevant for download to be selected from the drop down of available schemas in your Guardian instance. | MRV. | +| type | Receives data from the external source and passes them over the the next block. | **externalData**Block (Can't be changed). | +| tag | Unique name for the logic block. | mrv\_source. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| entityType | Specify the type of Entity this workflow block is for. | MRV. | +| schema | Pre-configured schemas relevant for download to be selected from the drop down of available schemas in your Guardian instance. | MRV. | + diff --git a/docs/available-policy-workflow-blocks/filtersaddonblock.md b/docs/available-policy-workflow-blocks/filtersaddonblock.md index 68132d9edd..bfe9bf272f 100644 --- a/docs/available-policy-workflow-blocks/filtersaddonblock.md +++ b/docs/available-policy-workflow-blocks/filtersaddonblock.md @@ -8,16 +8,16 @@ Note: This block is used for dropdown. You can add multiple blocks to 1 grid to | Block Property | Definition | Example Input | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | -| Type | A block for providing dynamic filters to DocumentsSourceAddOn Block | **filtersAddOn**Block (Can't be changed). | -| Tag | Unique name for the logic block. | report\__by\__project | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | -| Type | Filter type, so far only Dropdown type - allows the user to select one of the available values. | The list of available values is provided by DocumentsSourceAddonBlock | -| Can Be Empty | if true - if the filter is empty, then it is not taken into account when filtering. If false - then after filtering there will be an empty array | checked or unchecked | -| Field | the field by which the filtering will take place | document.credentialSubject.0.ref | -| Option Name | the field to be used as the label | document.credentialSubject.0.id | -| Option Value | the field that will act as the value | document.credentialSubject.0.id | +| type | A block for providing dynamic filters to DocumentsSourceAddOn Block | **filtersAddOn**Block (Can't be changed). | +| tag | Unique name for the logic block. | report\__by\__project | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | +| type | Filter type, so far only Dropdown type - allows the user to select one of the available values. | The list of available values is provided by DocumentsSourceAddonBlock | +| canBeEmpty | if true - if the filter is empty, then it is not taken into account when filtering. If false - then after filtering there will be an empty array | checked or unchecked | +| field | the field by which the filtering will take place | document.credentialSubject.0.ref | +| optionName | the field to be used as the label | document.credentialSubject.0.id | +| optionValue | the field that will act as the value | document.credentialSubject.0.id | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/information-workflow-block.md b/docs/available-policy-workflow-blocks/information-workflow-block.md index 0134eafec3..462cbd9f55 100644 --- a/docs/available-policy-workflow-blocks/information-workflow-block.md +++ b/docs/available-policy-workflow-blocks/information-workflow-block.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | A block type which can display a notification or a progress bar. | **InformationBlock** (Can't be changed). | -| Tag | Unique name for the logic block. | wait\_for\_approval. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | +| type | A block type which can display a notification or a progress bar. | **InformationBlock** (Can't be changed). | +| tag | Unique name for the logic block. | wait\_for\_approval. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/interfacedocumentssourceblock.md b/docs/available-policy-workflow-blocks/interfacedocumentssourceblock.md index f38a37f2bb..520c7bc0d3 100644 --- a/docs/available-policy-workflow-blocks/interfacedocumentssourceblock.md +++ b/docs/available-policy-workflow-blocks/interfacedocumentssourceblock.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | -------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -| Type | A block type which outputs information from the DB as grid. | **InterfaceDocumentsSource** Block (Can't be changed). | -| Tag | Unique name for the logic block. | sensors\_grid. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | -| Data Type | Specify the table to request the data from. | Current options are: Verifiable Credential, DID, Approve, or Hedera. | +| type | A block type which outputs information from the DB as grid. | **InterfaceDocumentsSource** Block (Can't be changed). | +| tag | Unique name for the logic block. | sensors\_grid. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Automatic update. The block is automatically re-rendered if any of the linked components gets updated. | Select the appropriate block from the dropdown. | +| dataType | Specify the table to request the data from. | Current options are: Verifiable Credential, DID, Approve, or Hedera. | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/introduction.md b/docs/available-policy-workflow-blocks/introduction.md index 78e3668200..fe7fbccc5b 100644 --- a/docs/available-policy-workflow-blocks/introduction.md +++ b/docs/available-policy-workflow-blocks/introduction.md @@ -23,6 +23,8 @@ Starting with the [Wikipedia definition](https://en.wikipedia.org/wiki/Workflow\ | retirementDocumentBlock | Receives the VC from the previous block and retires based on the rule(s). | [retirementdocumentblock.md](retirementdocumentblock.md "mention") | | wipeDocumentBlock | Makes a wipe of the token. Receives VC from the previous block. Passes a new VP to the next block. | [token-wipe-workflow-block.md](token-wipe-workflow-block.md "mention") | | calculateContainerBlock & calculateMathAddonBlock |

The blocks to calculate. calculateContainerBlock: Receives VC from the previous block. Passes the new VC to the next block.
calculateMathOnBlock: Child block for 'calculateContainerBlock'. Contains descriptions of variables and formulas.

| [calculatecontainerblock-and-calculatemathaddonblock.md](calculatecontainerblock-and-calculatemathaddonblock.md "mention") | -| aggregateDocumentBlock | Accumulates VC. Receives VC from the previous block. Passes an array of VCs to the next block. | [aggregate-data-workflow-block.md](aggregate-data-workflow-block.md "mention") | | reportBlock | The block container for TrustChain. | [reportblock-and-reportitemblock.md](reportblock-and-reportitemblock.md "mention") | | reportItemBlock | The block for setting up the elements of the TrustChain. | [reportblock-and-reportitemblock.md](reportblock-and-reportitemblock.md "mention") | +| Switch Block | This block transfers execution to one or more blocks depending on the parameters | [switchblock.md](switchblock.md "mention") | +| timerBlock | timer object which triggers the event | [timerblock.md](timerblock.md "mention") | +| aggregateDocumentBlock | block responsible for aggregation of the documents | [aggregatedocumentblock.md](aggregatedocumentblock.md "mention") | diff --git a/docs/available-policy-workflow-blocks/paginationaddon.md b/docs/available-policy-workflow-blocks/paginationaddon.md index 20c590692b..abde36d084 100644 --- a/docs/available-policy-workflow-blocks/paginationaddon.md +++ b/docs/available-policy-workflow-blocks/paginationaddon.md @@ -4,8 +4,8 @@ | Block Property | Definition | Example Input | | -------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | A block type which adds pagination to the InterfaceDocumentSourceBlock if added | **paginationAddon** (Can't be changed). | -| Tag | Unique name for the logic block. | | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or Unchecked | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| type | A block type which adds pagination to the InterfaceDocumentSourceBlock if added | **paginationAddon** (Can't be changed). | +| tag | Unique name for the logic block. | | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or Unchecked | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | diff --git a/docs/available-policy-workflow-blocks/reassigningblock.md b/docs/available-policy-workflow-blocks/reassigningblock.md index c446a74a23..10ee139de8 100644 --- a/docs/available-policy-workflow-blocks/reassigningblock.md +++ b/docs/available-policy-workflow-blocks/reassigningblock.md @@ -4,11 +4,12 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| Type | A block type which re-signs the document and change the user to document owner. | **reassigningBlock** (Can't be changed). | -| Tag | Unique name for the logic block. | wait\_for\_approval. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | +| type | A block type which re-signs the document and change the user to document owner. | **reassigningBlock** (Can't be changed). | +| tag | Unique name for the logic block. | wait\_for\_approval. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | | issuer | Person, who will be a Signer |

not set - Current User
owner - document Owner
policyOwner - Policy Owner

| | actor | Person, who will be next Block Owner |

not set - Current User
owner - document Owner
issuer - document Issuer

| + diff --git a/docs/available-policy-workflow-blocks/reportblock-and-reportitemblock.md b/docs/available-policy-workflow-blocks/reportblock-and-reportitemblock.md index 35d3fac013..8cdc7e58ae 100644 --- a/docs/available-policy-workflow-blocks/reportblock-and-reportitemblock.md +++ b/docs/available-policy-workflow-blocks/reportblock-and-reportitemblock.md @@ -6,11 +6,11 @@ | Block Property | Definition | Example Input | | -------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | Type of workflow logic | **report**Block(Can't be changed). | -| Tag | Unique name for the logic block. | report. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| type | Type of workflow logic | **report**Block(Can't be changed). | +| tag | Unique name for the logic block. | report. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | ## reportItemBlock diff --git a/docs/available-policy-workflow-blocks/request-workflow-block.md b/docs/available-policy-workflow-blocks/request-workflow-block.md index ac0d085db0..7bf3f5f773 100644 --- a/docs/available-policy-workflow-blocks/request-workflow-block.md +++ b/docs/available-policy-workflow-blocks/request-workflow-block.md @@ -4,14 +4,14 @@ | Block Property | Definition | Example Input | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -| Type | A type of the block which creates a form from the schema, and sends the document to the server. | **requestVCDocument**Block (Can't be changed). | -| Tag | Unique name for the logic block. | add\_new\_installer\_request. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Schema | Pre-configured schemas for the document relevant for policy action requests. Technically, it's the uuid of the schema, which will be used to build the form. | IRec-Application-Details (to be selected from the drop down of available schemas in your Guardian instance). | +| type | A type of the block which creates a form from the schema, and sends the document to the server. | **requestVCDocument**Block (Can't be changed). | +| tag | Unique name for the logic block. | add\_new\_installer\_request. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| schema | Pre-configured schemas for the document relevant for policy action requests. Technically, it's the uuid of the schema, which will be used to build the form. | IRec-Application-Details (to be selected from the drop down of available schemas in your Guardian instance). | | ID Type | Select the type of ID that is populated in the ID field of the Verifiable Credential document. | Current Options are: DID (creates a new DID), UUID (creates a new UUID), and Owner (which uses the DID of the current user). | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | +| stop propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | ### UI Properties @@ -63,4 +63,3 @@ VC Document ID of linked VC {% endswagger-parameter %} {% endswagger %} - diff --git a/docs/available-policy-workflow-blocks/retirementdocumentblock.md b/docs/available-policy-workflow-blocks/retirementdocumentblock.md index 9d80fd080d..ccd3b337da 100644 --- a/docs/available-policy-workflow-blocks/retirementdocumentblock.md +++ b/docs/available-policy-workflow-blocks/retirementdocumentblock.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | Receives the VC from the previous block and retires based on the rule(s). | **retirementDocument**Block(Can't be changed). | -| Tag | Unique name for the logic block. | retire\_token. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| type | Receives the VC from the previous block and retires based on the rule(s). | **retirementDocument**Block(Can't be changed). | +| tag | Unique name for the logic block. | retire\_token. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/roles-workflow-block.md b/docs/available-policy-workflow-blocks/roles-workflow-block.md index 4d1cab890d..eae7551920 100644 --- a/docs/available-policy-workflow-blocks/roles-workflow-block.md +++ b/docs/available-policy-workflow-blocks/roles-workflow-block.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | -------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | A block which determines a role for the user. | **PolicyRoles**Block (Can't be changed). | -| Tag | Unique name for the logic block. | choose\_role. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Installer. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Roles | Available roles from which the user can choose. | Select the appropriate roles from the dropdown. | +| type | A block which determines a role for the user. | **PolicyRoles**Block (Can't be changed). | +| tag | Unique name for the logic block. | choose\_role. | +| permissions | Which entity has rights to interact at this part of the workflow. | Installer. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| roles | Available roles from which the user can choose. | Select the appropriate roles from the dropdown. | ### UI Properties @@ -43,4 +43,3 @@ List of available roles {% endswagger-parameter %} {% endswagger %} - diff --git a/docs/available-policy-workflow-blocks/send-workflow-block.md b/docs/available-policy-workflow-blocks/send-workflow-block.md index b028f725c4..1e59161fd1 100644 --- a/docs/available-policy-workflow-blocks/send-workflow-block.md +++ b/docs/available-policy-workflow-blocks/send-workflow-block.md @@ -2,19 +2,20 @@ ### Properties -| Block Property | Definition | Example Input | Status | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| Type | A type of the block which can save a new or updated document. | **sendToGuardian**Block (Can't be changed). | | -| Tag | Unique name for the logic block. | save\_new\_approved\_document. | | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | | -| Data Type | Where to save the document. | Currently only options are: Verifiable Credential (send to the vc-documents DB table), DID (did-documents DB table), Approve (send to the approve DB table), or Hedera (document would be sent to the corresponding Policy topic in Hedera). | Deprecated | -| Entity Type | Gives the document a label in the DB. Needed for filtering. | Installer. | | -| Force New Document | Need to fill this out. | Checked or Unchecked. | | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | | -| Options | List of attributes, which is added to the VC when it is being persistent. Can be used for more flexible filtration. |

"name": "status"

"value": "Minted",

| | -| Data Source | Where to send Data | Database / Hedera | | -| Document Type | Type of Document | VC / DID / VP | | -| Topic | Topic to send a document if 'dataSource' = 'Hedera' | topic | | -| Topic Owner | if ‘Hedera Topic’ is selected for the ‘Source Type’ a new optional property ‘Topic Owner’ appears which shows which field determines the User, who will own the topic of the document. This is because in ‘Hedera Topic’ only the template of Topic is selected, not the the topic itself. |

Current User - user whose credentials were used to make the current post request

Document Owner - creator of the document (has default value)

Document Issuer - user which was the last to sign the document

| | +| Block Property | Definition | Example Input | Status | +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| type | A type of the block which can save a new or updated document. | **sendToGuardian**Block (Can't be changed). | | +| tag | Unique name for the logic block. | save\_new\_approved\_document. | | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | | +| dataType | Where to save the document. | Currently only options are: Verifiable Credential (send to the vc-documents DB table), DID (did-documents DB table), Approve (send to the approve DB table), or Hedera (document would be sent to the corresponding Policy topic in Hedera). | Deprecated | +| entityType | Gives the document a label in the DB. Needed for filtering. | Installer. | | +| forceNewDocument | Need to fill this out. | Checked or Unchecked. | | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked. | | +| options | List of attributes, which is added to the VC when it is being persistent. Can be used for more flexible filtration. |

"name": "status"

"value": "Minted",

| | +| dataSource | Where to send Data | Database / Hedera | | +| documentType | Type of Document | VC / DID / VP | | +| topic | Topic to send a document if 'dataSource' = 'Hedera' | topic | | +| topicOwner | if ‘Hedera Topic’ is selected for the ‘Source Type’ a new optional property ‘Topic Owner’ appears which shows which field determines the User, who will own the topic of the document. This is because in ‘Hedera Topic’ only the template of Topic is selected, not the the topic itself. |

Current User - user whose credentials were used to make the current post request

Document Owner - creator of the document (has default value)

Document Issuer - user which was the last to sign the document

| | + diff --git a/docs/available-policy-workflow-blocks/step-workflow-block.md b/docs/available-policy-workflow-blocks/step-workflow-block.md index d436ea28e3..254d511fe8 100644 --- a/docs/available-policy-workflow-blocks/step-workflow-block.md +++ b/docs/available-policy-workflow-blocks/step-workflow-block.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | -------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | Similar to the **InterfaceContainer**Block, with the difference that it can only render a single child element. | **InterfaceStep**Block (Can't be changed). | -| Tag | Unique name for the logic block. | CSD01 Document. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Cyclic | Go back one step to enable the creation of the previous object. | Checked or unchecked. | +| type | Similar to the **InterfaceContainer**Block, with the difference that it can only render a single child element. | **InterfaceStep**Block (Can't be changed). | +| tag | Unique name for the logic block. | CSD01 Document. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| cyclic | Go back one step to enable the creation of the previous object. | Checked or unchecked. | ### UI Properties @@ -45,4 +45,3 @@ Contained blocks array Current Step {% endswagger-parameter %} {% endswagger %} - diff --git a/docs/available-policy-workflow-blocks/switchblock.md b/docs/available-policy-workflow-blocks/switchblock.md new file mode 100644 index 0000000000..b8bdac0a77 --- /dev/null +++ b/docs/available-policy-workflow-blocks/switchblock.md @@ -0,0 +1,17 @@ +# switchBlock + +### Properties + +| Block Property | Definition | Example Input | +| ------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tag | Unique name for the logic Block. | SwitchBlock | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or Unchecked | +| On errors | Called if the system error has occurs in the Block |

  • No action
  • Retry
  • Go to step
  • Go to tag
| +| stop Propagation | End processing here, don't pass control to the next block. | Checked or Unchecked | +| Execution Flow | Flow of Execution |
  1. First True - only the ‘branch’ under the first ‘true’ condition gets executed.
  2. 2. All True - branches under all conditions evaluated as ‘true’ get executed.
| +| Condition(i) | number of the condition | if (field(0))>1 | +| Condition Type | Type of the condition | Equal - resolves as true if the condition is true - Not Equal - resolved as true if the condition is false - Unconditional - always true | +| Condition (String) | condition expression which can contain math formulas | field0 > 0 | +| Actor | the permissions/role context of the execution of the next block | Current User - user under whom the condition is evaluated - Document Owner - the creator of the document - Document Issuer - the signator of the document | +| Target Block | the block which gets executed when the condition is true | Block\_1 | diff --git a/docs/available-policy-workflow-blocks/timerblock.md b/docs/available-policy-workflow-blocks/timerblock.md new file mode 100644 index 0000000000..6fa8707ff3 --- /dev/null +++ b/docs/available-policy-workflow-blocks/timerblock.md @@ -0,0 +1,18 @@ +# TimerBlock + +### Properties + +Input - document which is needed to start the timer for different users separately. + +| Block Property | Definition | Example Input | +| ---------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tag | Unique name for the logic block. | timerBlock | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| On errors | Called if the system error has occurs in the Block |

  • No action
  • Retry
  • Go to step
  • Go to tag
| +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| Start Date | date/time to start the timer | 16-05-2022 16:00 (UTC+04:00) | +| End Date | date/time to stop the timer | 16-05-2022 16:00 (UTC+04:00) | +| Period | specification of the period which which timer triggers (starting from the Start Date) |

Yearly

Monthly

Weekly

Daily

Hourly

Custom - advanced period

configuration

If ‘Period’ = ‘Custom’
Mask - cron mask for timer (example: https://crontab.guru/)
Interval (number) - trigger timer on every tick
(e.g. every two days)

| +| Custom Period | open dialogue window to set Mask and Interval | 0 12 \*\*\*\* 4 | diff --git a/docs/available-policy-workflow-blocks/token-mint-workflow-block.md b/docs/available-policy-workflow-blocks/token-mint-workflow-block.md index ff81f34c1b..698ac402d1 100644 --- a/docs/available-policy-workflow-blocks/token-mint-workflow-block.md +++ b/docs/available-policy-workflow-blocks/token-mint-workflow-block.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | Receives the VC from the previous block and mints based on the rule(s). | **mintDocument**Block(Can't be changed). | -| Tag | Unique name for the logic block. | mint\_token. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| tag | Unique name for the logic block. | mint\_token. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| On errors | | | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | ### UI Properties diff --git a/docs/available-policy-workflow-blocks/token-wipe-workflow-block.md b/docs/available-policy-workflow-blocks/token-wipe-workflow-block.md index f3e249693b..c4e883f329 100644 --- a/docs/available-policy-workflow-blocks/token-wipe-workflow-block.md +++ b/docs/available-policy-workflow-blocks/token-wipe-workflow-block.md @@ -4,12 +4,12 @@ | Block Property | Definition | Example Input | | ---------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| Type | Type of workflow logic block. | **wipeDocument**Block (Can't be changed). | -| Tag | Unique name for the logic block. | wipe\_token. | -| Permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | -| Default Active | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | -| Dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | -| Stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | +| type | Type of workflow logic block. | **wipeDocument**Block (Can't be changed). | +| tag | Unique name for the logic block. | wipe\_token. | +| permissions | Which entity has rights to interact at this part of the workflow. | Root Authority. | +| defaultActive | Shows whether this block is active at this time and whether it needs to be shown. | Checked or unchecked. | +| dependencies | Establish workflow dependancies that need to be completed prior. | Select the appropriate block from the dropdown. | +| stop Propagation | End processing here, don't pass control to the next block. | Checked or unchecked. | ### UI Properties diff --git a/docs/demo-guide/api-workflow-of-irec-demo.md b/docs/demo-guide/api-workflow-of-irec-demo.md new file mode 100644 index 0000000000..a1a6cb87dd --- /dev/null +++ b/docs/demo-guide/api-workflow-of-irec-demo.md @@ -0,0 +1,12169 @@ +# iREC 2 API Demo Guide + +## Root Authority + +### Create Root Account + +{% swagger method="post" path="" baseUrl="/account/register" summary="Creating Root Authority" %} +{% swagger-description %} +To create a Root Account +{% endswagger-description %} + +{% swagger-parameter in="body" name="username" type="String" required="true" %} +rootUsername +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="password" type="String" required="true" %} +rootPassword +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="role" type="String" required="true" %} +ROOT_AUTHORITY +{% endswagger-parameter %} + +{% swagger-response status="201: Created" description="Successful Operation" %} +```javascript +{ + "username": "1tckto80", + "password": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", + "did": null, + "parent": null, + "role": "ROOT_AUTHORITY", + "id": "627d4b99ab3cae7c07025893" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Login as Root Authority + +{% swagger method="post" path="" baseUrl="/accounts/login" summary="Login to the Root Account" %} +{% swagger-description %} +Login as Root Authority +{% endswagger-description %} + +{% swagger-parameter in="body" name="username" type="String" required="true" %} +username +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="password" type="String" required="true" %} +Password +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "username": "1tckto80", + "did": null, + "role": "ROOT_AUTHORITY", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjF0Y2t0bzgwIiwiZGlkIjpudWxsLCJyb2xlIjoiUk9PVF9BVVRIT1JJVFkiLCJpYXQiOjE2NTIzNzk5MDR9.xo6WrNhW5uPfpxBICgTHqyip7TFk2GnrUHtMTJ-TKgU" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Generating Root Key + +{% swagger method="get" path="" baseUrl="/demo/randomKey" summary="To Generate Root Key" %} +{% swagger-description %} +Generating Root Key +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "0.0.34751301", + "key": "302e020100300506032b65700422042076ccbf8eec6031299bbcdaf14f97b3de116e5b809e8ae3f8a55f7e035aa0fbdc" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Update Root Profile + +{% swagger method="put" path="{rootUsername}" baseUrl="/profiles/" summary="Updating Profile of Root Authority" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="hederaAccountID" type="String" required="true" %} +rootID +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hederaAccountKey" type="Key" required="true" %} +rootKey +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="vcDocument" type="Array" required="false" %} + +{% endswagger-parameter %} +{% endswagger %} + +### Get Root Profile + +{% swagger method="get" path="" baseUrl="/profiles/{rootUsername}" summary="Getting Root Authority Profile Details" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "username": "1tckto80", + "role": "ROOT_AUTHORITY", + "did": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "parent": null, + "hederaAccountId": "0.0.34751301", + "confirmed": true, + "failed": false, + "hederaAccountKey": null, + "topicId": "0.0.34751333", + "didDocument": { + "id": "627d553d0f12a18fef5f1d52", + "did": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "document": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://ns.did.ai/transmute/v1" + ], + "id": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "verificationMethod": [ + { + "id": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333#did-root-key", + "type": "Ed25519VerificationKey2018", + "controller": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "publicKeyBase58": "B5Myaf7Uhfg8t5XWjm6QZCd6HB44xqyiiBXVDFokYEzR" + } + ], + "authentication": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333#did-root-key", + "assertionMethod": [ + "#did-root-key" + ] + }, + "createDate": "2022-05-12T18:43:09.816Z", + "updateDate": "2022-05-12T18:43:09.817Z", + "status": "CREATE", + "messageId": "1652380991.675947000", + "topicId": "0.0.34751333" + }, + "vcDocument": { + "id": "627d553d0f12a18fef5f1d53", + "owner": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "hash": "D9A1uvPHUsjn869gswTkhQTQUJcpRaihSwnRhqF1L9Mm", + "document": { + "id": "e0a4ddac-682f-4b64-8e50-dfa2e6d98d9d", + "type": [ + "VerifiableCredential" + ], + "issuer": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "issuanceDate": "2022-05-12T18:43:09.839Z", + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "credentialSubject": [ + { + "id": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333" + } + ], + "proof": { + "type": "Ed25519Signature2018", + "created": "2022-05-12T18:43:09Z", + "verificationMethod": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333#did-root-key", + "proofPurpose": "assertionMethod", + "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..mWMjPMSIf6E8U7ZJTve-L4JWDu6mrWVsVgdkRz4Rsk-oH4l27A1ApRGDo7FrsSkmQjQqbixJ8IxBtraOs-fRCA" + } + }, + "createDate": "2022-05-12T18:43:09.924Z", + "updateDate": "2022-05-12T18:43:09.924Z", + "hederaStatus": "ISSUE", + "signature": 0, + "type": "ROOT_AUTHORITY", + "option": {}, + "messageId": "1652380995.021714404", + "topicId": "0.0.34751333" + } +} +``` +{% endswagger-response %} +{% endswagger %} + +## User + +### Create User Account + +{% swagger method="post" path="" baseUrl="/accounts/register" summary="Creating User Account" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="username" type="String" required="true" %} +rootUsername +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="password" type="String" required="true" %} +rootPassword +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="role" type="String" required="true" %} +USER +{% endswagger-parameter %} + +{% swagger-response status="201: Created" description="Successful Operation" %} +```javascript +{ + "username": "keovlmcy", + "password": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", + "did": null, + "parent": null, + "role": "USER", + "id": "627d5740ab3cae7c07025895" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Login to User Account + +{% swagger method="post" path="" baseUrl="/accounts/login" summary="Login as User" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="username" type="String" required="true" %} +rootUsername +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="password" type="String" required="true" %} +rootPassword +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "username": "keovlmcy", + "did": null, + "role": "USER", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imtlb3ZsbWN5IiwiZGlkIjpudWxsLCJyb2xlIjoiVVNFUiIsImlhdCI6MTY1MjM4MTcyNn0.T6ptsaQmCvHUVUfqcO3LJHY4GVZJn9Sbgt5N9WpZ_bI" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Generate User Key + +{% swagger method="get" path="" baseUrl="/demo/randomKey" summary="Generating User Key" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "0.0.34751370", + "key": "302e020100300506032b657004220420ba1b0e7b60f40e0032c21fa1c19eb6e4a09a53ad217c80ab08f6b0720d6ffbf3" +} +``` +{% endswagger-response %} +{% endswagger %} + +### Update User Profile + +{% swagger method="put" path="" baseUrl="/profiles/{userUsername}" summary="Updating User Profiles" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="hederaAccountID" type="ID" required="true" %} +UserID +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hederaAccountKey" type="Key" required="true" %} +UserKey +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="parent" type="DID" required="true" %} +rootDID +{% endswagger-parameter %} +{% endswagger %} + +### Get User Profile + +{% swagger method="get" path="" baseUrl="/profiles/{userUsername}" summary="Getting User Profile Details" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "username": "keovlmcy", + "role": "USER", + "did": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333", + "parent": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "hederaAccountId": "0.0.34751370", + "confirmed": true, + "failed": false, + "hederaAccountKey": null, + "topicId": "0.0.34751333", + "didDocument": { + "id": "627d595c0f12a18fef5f1d54", + "did": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333", + "document": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://ns.did.ai/transmute/v1" + ], + "id": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333", + "verificationMethod": [ + { + "id": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333#did-root-key", + "type": "Ed25519VerificationKey2018", + "controller": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333", + "publicKeyBase58": "EpLUuXpqFSChqCgmDLcKqsm1EBhVRXLxH7juwu3iEYtw" + } + ], + "authentication": "did:hedera:testnet:6PthfKmdjeKjXoJ9XULiUwJMLbooHoEHgsqoPTT9LArW;hedera:testnet:tid=0.0.34751333#did-root-key", + "assertionMethod": [ + "#did-root-key" + ] + }, + "createDate": "2022-05-12T19:00:44.279Z", + "updateDate": "2022-05-12T19:00:44.279Z", + "status": "CREATE", + "messageId": "1652382046.878940000", + "topicId": "0.0.34751333" + } +} +``` +{% endswagger-response %} +{% endswagger %} + +## Policy + +### New Policy + +#### Import Policy + +{% swagger method="post" path="" baseUrl="/policies/import/message" summary="Importing Policy" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="messageID" type="ID" required="true" %} +1651598638.021817000 +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + { + "id": "627e97fb0f12a18fef5f1d61", + "uuid": "35461391-ddec-4c05-a446-da0c9324d1b2", + "name": "iRec_2_1650456840748_1652463611568", + "description": "iRec Description", + "topicDescription": "iRec Description", + "config": { + "blockType": "interfaceContainerBlock", + "permissions": [ + "ANY_ROLE" + ], + "id": "5de4c484-e9fa-4e4e-a3b0-70d945441a34", + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "children": [ + { + "id": "18639325-e036-4773-9eaa-6ccbb965b19d", + "tag": "choose_role", + "blockType": "policyRolesBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "NO_ROLE" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Registration", + "description": "Choose a role" + }, + "roles": [ + "Registrant" + ] + }, + { + "id": "c769991c-af8d-4292-989c-a697cd047f73", + "tag": "registrants_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "1ba36c5a-78ac-4081-80f4-7ac8693df3e1", + "tag": "registrants_workflow_steps", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "f2c1674d-443f-435f-839f-4325e6ca0698", + "tag": "create_application", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "page", + "title": "Registrant Application" + }, + "presetFields": [], + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5", + "idType": "OWNER" + }, + { + "id": "0292bfb4-ebdf-4ff7-a927-ce9fb58925d0", + "tag": "save_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "entityType": "registrant", + "topic": "Project", + "dataSource": "hedera", + "documentType": "vc", + "topicOwner": "user" + }, + { + "id": "fed49259-8ce2-4330-910b-02ee7719b499", + "tag": "create_application(db)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "47dcda17-a066-4713-8b37-3a7e53f30be1", + "tag": "wait_for_approve", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "description": "The page will refresh automatically once the application is approved.", + "type": "text", + "title": "Submitted for Approval" + }, + "stopPropagation": true + }, + { + "id": "27cecf69-1fd4-47d9-b42d-93218e9d1023", + "tag": "save_application_status(approve)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "9e5c60b1-18e3-4770-9771-da9af49811c4", + "tag": "sign_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "issuer": "policyOwner", + "actor": "owner" + }, + { + "id": "ee7d2cfa-ec36-46dc-accc-0cad35f270d0", + "tag": "save_copy_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "registrant(Approved)", + "topicOwner": "owner" + }, + { + "id": "47a2c964-23dc-41ce-ae4f-cb4886c7a076", + "tag": "save_copy_application", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant(Approved)", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "4ba98a84-ac13-4f74-b2ec-4cb5be6efae7", + "tag": "registrants_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "a4584ad6-fc88-485c-99d4-368b5be76527", + "tag": "devices_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "53e0e097-a9df-4d9a-95e7-8c5ca0acf205", + "tag": "devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "a92ef034-74f8-4e80-a7bb-bd40217ce784", + "tag": "devices_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af", + "dataType": "vc-documents", + "onlyOwnDocuments": true + }, + { + "id": "44f94b84-d19c-4874-adba-e337c63c889c", + "tag": "devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device(Approved)", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "title": "Issue Request", + "name": "option.status", + "type": "text", + "bindGroup": "devices_source", + "width": "150px" + }, + { + "title": "Issue Request", + "name": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "create_issue_request_form", + "width": "150px", + "bindGroup": "devices_source(approved)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "create_issue_request", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "9851be69-140e-458a-b9fa-86610abf8944", + "tag": "new_device", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "86c88ac1-6f89-4e76-9f2b-28ecfb8ae984", + "tag": "create_device_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [ + { + "id": "9929592e-3661-405e-b194-9f0fc25cbec8", + "tag": "current_registrant", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant(Approved)", + "field": "type", + "type": "equal" + } + ], + "onlyOwnDocuments": true, + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5", + "dataType": "vc-documents" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create New Device", + "dialogContent": "Device Registration" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "id", + "readonly": false + }, + { + "name": "field1", + "title": "Date", + "readonly": false + }, + { + "name": "field2", + "title": "Is the Registrant also the owner of the Device? (provide evidence) ", + "readonly": false + }, + { + "name": "field3", + "title": "Registrant Details", + "value": "field2", + "readonly": false + }, + { + "name": "field4", + "title": "Production Device Details", + "readonly": false + }, + { + "name": "field5", + "title": "Energy Sources", + "readonly": false + } + ], + "idType": "DID", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af", + "preset": true, + "presetSchema": "#049308d8-d519-427c-bfae-8c77e7671da5" + }, + { + "id": "a798348d-7882-4264-81ca-97d37d60aa43", + "tag": "save_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "device", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "229e0f65-05c0-4af3-b882-cc0638da7654", + "tag": "create_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "entityType": "device", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + }, + { + "id": "f28a4529-e402-44e7-9fe6-6c2342babe7e", + "tag": "new_issue_request", + "blockType": "interfaceStepBlock", + "defaultActive": false, + "children": [ + { + "id": "76449598-fdef-4b78-8836-ed986e55aa75", + "tag": "create_issue_request_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create Issue Request", + "dialogContent": "New Issue Request", + "buttonClass": "link" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0", + "readonly": false + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "id", + "readonly": false + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field3", + "readonly": false + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field4", + "readonly": false + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "readonly": false + }, + { + "name": "field5", + "title": "Last registration date", + "readonly": false + }, + { + "name": "field6", + "title": "Production Period Start Date", + "readonly": false + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "readonly": false + }, + { + "name": "field8", + "title": "Production Period End Date", + "readonly": false + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "readonly": false + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "readonly": false + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "readonly": false + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "readonly": false + }, + { + "name": "field13", + "title": "Type d: Other", + "readonly": false + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "readonly": false + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "readonly": false + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "readonly": false + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "username", + "readonly": false + }, + { + "name": "field18", + "title": "Account number", + "value": "hederaAccountId", + "readonly": false + } + ], + "idType": "UUID", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671", + "preset": true, + "presetSchema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af" + }, + { + "id": "60c1ae67-5b4d-4c4b-926f-6afd56e5968f", + "tag": "save_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "issue_request", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "38157ad3-c5e8-4e83-a127-5fc463144b5e", + "tag": "create_issue_request", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "issue_request", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "5d97928a-7ad0-4d12-8a24-0887d2c462fa", + "tag": "issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "5842e60f-ffcf-4cde-bb7c-d0a7d564b58b", + "tag": "issue_requests_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "148d8640-91b6-4453-84a0-88410554e760", + "tag": "issue_requests_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "de8f42d5-6901-441f-9d6f-f7d10ae9fa0f", + "tag": "issue_by_device", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "8063ccbb-3328-490f-ae92-fd773e372e08", + "tag": "devices_source_from_filters", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "field": "document.credentialSubject.0.ref", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Status", + "type": "text" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "3da2bbb7-0c4a-4ec9-8c38-b217af2da35b", + "tag": "token_history_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "2eaa8a53-0379-4479-a53f-7b397b9b41d8", + "tag": "token_history_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "a9abb318-30b3-4b53-bd19-292047b0935b", + "tag": "token_history_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "962714b7-8bb5-4958-841a-6b370cfe1192", + "tag": "token_history_source_filter", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "8b5a74e6-fb37-432d-9223-e89065dca7e5", + "tag": "devices_source_from_filters2", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id", + "field": "document.verifiableCredential.0.credentialSubject.0.field1" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents", + "onlyOwnDocuments": false + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + } + ] + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + }, + { + "id": "ba6926b1-be6d-46a0-8986-c155b9865331", + "tag": "save_application_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "3941044d-d593-4246-b7f7-20e53057e711", + "tag": "application_rejected", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Rejected", + "description": "Your application was rejected", + "type": "text" + }, + "stopPropagation": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "550b6cc0-35b5-4e81-bfbb-496ffc78e621", + "tag": "evident_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "d1edace7-9ec6-4bc0-9bf0-acaded28fe10", + "tag": "approve_application_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "869280f7-626a-4e5e-8c88-6d2d14ddbc88", + "tag": "registrants_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "283a4eee-01fe-4501-b6df-33cae2c2fd68", + "tag": "registrants_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5" + }, + { + "id": "c4a0dc23-d30c-44f2-95c1-bb46be8cfedb", + "tag": "registrants_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Legal Name", + "name": "document.credentialSubject.0.field1.field0", + "type": "text" + }, + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Operation", + "name": "option.status", + "type": "text", + "width": "250px", + "bindGroup": "registrants_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_registrant_btn", + "width": "250px", + "bindGroup": "registrants_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "save_application_status(approve)", + "save_application_status(reject)" + ] + }, + { + "id": "92365a5c-d7bc-4985-b425-cf1340a4f1c7", + "tag": "approve_registrant_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_application_status(approve)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_application_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Applications" + } + }, + { + "id": "584752e1-d0bb-4b21-b183-3690207bbdb2", + "tag": "approve_device_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "888cc08a-9348-41cf-a8fd-365401acf40e", + "tag": "approve_devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "8b0438fd-32e3-4666-bdee-54ec071789d3", + "tag": "approve_devices_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af" + }, + { + "id": "bda94def-d1ba-4fa1-b03a-7c7035a12df5", + "tag": "approve_devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field3.field0", + "type": "text" + }, + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "approve_devices_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_device_btn", + "width": "250px", + "bindGroup": "approve_devices_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "5404a5bf-32d6-483e-8cce-f3ed344eaab4", + "tag": "approve_device_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_device_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_device_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "0495a898-4ae3-4ee1-bf89-1b7bdec3d11b", + "tag": "save_device_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "stopPropagation": false, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "038c7fbc-38cc-4bc5-9600-77594723819e", + "tag": "sign_device_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "actor": "", + "issuer": "policyOwner" + }, + { + "id": "9ebf31d2-4ff2-4048-b610-7db47b425e0e", + "tag": "save_copy_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "device(Approved)", + "topicOwner": "owner" + }, + { + "id": "e0fa120a-48d0-4e29-a5aa-c5645e997ea2", + "tag": "save_copy_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "device(Approved)", + "dataType": "", + "stopPropagation": true, + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "0e082400-1b0f-4229-830f-1e03b5767e17", + "tag": "save_device_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "stopPropagation": true, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "0df2fd8c-1614-4a07-94b1-870e2638e78d", + "tag": "approve_issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "5197e08f-0cbe-4ded-a0c0-4657a8ee1c3f", + "tag": "issue_requests_grid(evident)", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "499c9c18-2375-4a40-a460-92b8d8f92e96", + "tag": "issue_requests_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671" + }, + { + "id": "6d352c31-5602-486c-bd35-ef35de6b87ee", + "tag": "issue_requests_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "issue_requests_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_issue_requests_btn", + "width": "250px", + "bindGroup": "issue_requests_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + }, + { + "id": "02f54956-6dd8-4755-aa52-b08674774be9", + "tag": "approve_issue_requests_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_issue_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_issue_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "c272b91f-b2b9-4e52-bd80-c84505d77770", + "tag": "mint_events", + "blockType": "interfaceContainerBlock", + "defaultActive": false, + "children": [ + { + "id": "dca3ca61-0c75-4530-be9e-847e5db8c251", + "tag": "save_issue_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "issue_request", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "7055730e-0f81-426d-ad3a-032e2d4fc54f", + "tag": "sign_issue_by_issuer", + "blockType": "calculateContainerBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "inputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "outputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "inputSchema": "#fb069289-5bdd-4bba-972a-68b33eca3671", + "outputSchema": "#fb069289-5bdd-4bba-972a-68b33eca3671" + }, + { + "id": "739a2a05-ec36-4b1c-b27e-368219e8dd7f", + "tag": "save_copy_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "topicOwner": "owner" + }, + { + "id": "cad6e6c9-2408-40a8-9c9f-ab19682d8998", + "tag": "save_copy_issue", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minting" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "6ca507d0-7512-4578-85c5-a85744e8f0ac", + "tag": "mint_token", + "blockType": "mintDocumentBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "tokenId": "0.0.34804363", + "rule": "field7" + }, + { + "id": "14ff06fa-9c76-4468-b873-c59d751b0029", + "tag": "save_issue_status(minted)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minted" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "54e33f31-76b0-4e7d-ac60-af515c9c22be", + "tag": "save_issue_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "entityType": "issue_request", + "dataType": "", + "stopPropagation": true, + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "872d5b8f-a8c6-4e94-a24a-ab3f35762e8c", + "tag": "VP", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "0bdac0af-6539-4395-b365-1e8187580a46", + "tag": "vp_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "d64e68d9-f396-4817-bc38-89def589f582", + "tag": "vp_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "HASH", + "name": "hash", + "tooltip": "", + "type": "text" + }, + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + }, + { + "title": "TrustChain", + "name": "hash", + "tooltip": "", + "type": "button", + "action": "link", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "trustChainBlock", + "content": "View TrustChain", + "width": "150px" + } + ] + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + }, + { + "id": "837286ed-4931-4245-98b5-2365b2aa1b5f", + "tag": "trust_chain", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "7bc21e88-af74-48d7-8722-859e06dcdc2c", + "tag": "trustChainBlock", + "blockType": "reportBlock", + "defaultActive": true, + "children": [ + { + "id": "61cec38a-734e-4dbf-a93f-213be5d3e0a2", + "tag": "MintTokenItem", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "actionId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Token", + "description": "Token[s] minted." + }, + { + "id": "191975eb-42b2-4454-97c4-ae6a37d9b62c", + "tag": "issue_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request(Approved)" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "documentId" + } + ], + "variables": [ + { + "value": "document.credentialSubject.0.id", + "name": "issueId" + }, + { + "name": "registrantId", + "value": "document.credentialSubject.0.field0" + }, + { + "name": "deviceId", + "value": "document.credentialSubject.0.field1" + } + ], + "visible": true, + "iconType": "COMMON", + "title": "Issue Request Review", + "description": "Issue Request processed." + }, + { + "id": "6c9d4aca-ee28-4b66-81d0-db6feec7b458", + "tag": "issue_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.credentialSubject.0.id", + "value": "issueId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Registrant submitted Issue Request to Issuer.", + "title": "Issue Request" + }, + { + "id": "01d36d6f-da44-416c-87af-82512f920795", + "tag": "device_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "type": "equal", + "field": "type", + "value": "device(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Device registration request processed.", + "title": "Device Review" + }, + { + "id": "9e404222-5247-4923-9a1e-293fad6619f8", + "tag": "device_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "device", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Device Registration", + "description": "Production Facility/Device registration request submitted to Issuer." + }, + { + "id": "9da21b8a-3018-4b91-8b34-b293d9d4ec53", + "tag": "registrant_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "value", + "field": "type", + "value": "registrant(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application/KYC processed.", + "title": "Application Review" + }, + { + "id": "d01cb7b3-1b8f-46ba-9e06-0c34cedfeb2e", + "tag": "registrant_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application submitted to Issuer.", + "title": "Registrant Application" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "TrustChain" + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + } + ] + }, + "status": "DRAFT", + "creator": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "owner": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "policyRoles": [ + "Registrant" + ], + "policyTopics": [ + { + "name": "Project", + "description": "Project", + "type": "any", + "static": false + } + ], + "registeredUsers": {}, + "topicId": "0.0.34804358", + "instanceTopicId": "0.0.34251041", + "policyTag": "Tag_1652463578256", + "createDate": "2022-05-13T17:40:11.584Z" + } +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Publish Policy + +{% swagger method="put" path="{policyId}/publish" baseUrl="/policies/" summary="Publishing Policy" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="policyVersion" type="String" required="true" %} +1.0.0 +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "policies": [ + { + "id": "627e97fb0f12a18fef5f1d61", + "uuid": "35461391-ddec-4c05-a446-da0c9324d1b2", + "name": "iRec_2_1650456840748_1652463611568", + "version": "1.0.0", + "description": "iRec Description", + "topicDescription": "iRec Description", + "config": { + "blockType": "interfaceContainerBlock", + "permissions": [ + "ANY_ROLE" + ], + "id": "3909fb19-5181-48cb-91e4-8230c0e83521", + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "children": [ + { + "id": "23f73d24-3482-4cef-9185-3605bb84384e", + "tag": "choose_role", + "blockType": "policyRolesBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "NO_ROLE" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Registration", + "description": "Choose a role" + }, + "roles": [ + "Registrant" + ] + }, + { + "id": "a653e179-779f-4b1b-8d3b-986e534329c2", + "tag": "registrants_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "f99af4b5-d80c-4caa-9c7a-8c5e6519e2ee", + "tag": "registrants_workflow_steps", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "8a0cad0d-81d2-499f-be21-b2bea383114a", + "tag": "create_application", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "page", + "title": "Registrant Application" + }, + "presetFields": [], + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5&1.0.0", + "idType": "OWNER" + }, + { + "id": "665ba2f2-dbda-49a6-9eb8-bbf4bb0315e8", + "tag": "save_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "entityType": "registrant", + "topic": "Project", + "dataSource": "hedera", + "documentType": "vc", + "topicOwner": "user" + }, + { + "id": "0bd2c4a3-29f8-4442-87c6-6c0fea7d423b", + "tag": "create_application(db)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "7615c4b3-9f48-4fbf-b100-0d41adab690c", + "tag": "wait_for_approve", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "description": "The page will refresh automatically once the application is approved.", + "type": "text", + "title": "Submitted for Approval" + }, + "stopPropagation": true + }, + { + "id": "f5068d63-1fcf-43f7-8965-5f6d2957dc24", + "tag": "save_application_status(approve)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "f82cbe72-6695-42a8-b9de-652ff8e705ae", + "tag": "sign_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "issuer": "policyOwner", + "actor": "owner" + }, + { + "id": "36a45563-6eae-48d7-96c8-0c5db77c02dc", + "tag": "save_copy_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "registrant(Approved)", + "topicOwner": "owner" + }, + { + "id": "274df982-6e7c-491a-8db6-8eb0e26d3d38", + "tag": "save_copy_application", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant(Approved)", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "f7ef10c9-95de-4d02-9a38-3b08995abe3e", + "tag": "registrants_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "c4cb948d-654e-467b-94fc-5a4f7eff28c6", + "tag": "devices_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "b3d11e4b-4e5f-457e-9072-661d9e81cd3f", + "tag": "devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "0d03ac0f-a88b-45cb-a0d8-2e61b9b0bcd2", + "tag": "devices_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0", + "dataType": "vc-documents", + "onlyOwnDocuments": true + }, + { + "id": "cdc2ebc7-e7cc-4111-a936-cf06c48a0e91", + "tag": "devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device(Approved)", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "title": "Issue Request", + "name": "option.status", + "type": "text", + "bindGroup": "devices_source", + "width": "150px" + }, + { + "title": "Issue Request", + "name": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "create_issue_request_form", + "width": "150px", + "bindGroup": "devices_source(approved)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "create_issue_request", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "807061c4-2aad-4fa1-8666-232e735f02cb", + "tag": "new_device", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "b1551968-23e5-4c1c-8953-53e7867a08ea", + "tag": "create_device_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [ + { + "id": "8412cd52-e675-474a-8b40-527e5e5329fd", + "tag": "current_registrant", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant(Approved)", + "field": "type", + "type": "equal" + } + ], + "onlyOwnDocuments": true, + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5&1.0.0", + "dataType": "vc-documents" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create New Device", + "dialogContent": "Device Registration" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "id", + "readonly": false + }, + { + "name": "field1", + "title": "Date", + "readonly": false + }, + { + "name": "field2", + "title": "Is the Registrant also the owner of the Device? (provide evidence) ", + "readonly": false + }, + { + "name": "field3", + "title": "Registrant Details", + "value": "field2", + "readonly": false + }, + { + "name": "field4", + "title": "Production Device Details", + "readonly": false + }, + { + "name": "field5", + "title": "Energy Sources", + "readonly": false + } + ], + "idType": "DID", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0", + "preset": true, + "presetSchema": "#049308d8-d519-427c-bfae-8c77e7671da5&1.0.0" + }, + { + "id": "af746648-3b74-4400-aba1-473aaf39a52e", + "tag": "save_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "device", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "f0abcf28-f793-4d25-826c-43cec8ba9b57", + "tag": "create_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "entityType": "device", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + }, + { + "id": "cdb3d064-7174-4fff-bd3d-054c8e651649", + "tag": "new_issue_request", + "blockType": "interfaceStepBlock", + "defaultActive": false, + "children": [ + { + "id": "924d5826-77fc-41c8-b308-fe1813ad3544", + "tag": "create_issue_request_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create Issue Request", + "dialogContent": "New Issue Request", + "buttonClass": "link" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0", + "readonly": false + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "id", + "readonly": false + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field3", + "readonly": false + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field4", + "readonly": false + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "readonly": false + }, + { + "name": "field5", + "title": "Last registration date", + "readonly": false + }, + { + "name": "field6", + "title": "Production Period Start Date", + "readonly": false + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "readonly": false + }, + { + "name": "field8", + "title": "Production Period End Date", + "readonly": false + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "readonly": false + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "readonly": false + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "readonly": false + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "readonly": false + }, + { + "name": "field13", + "title": "Type d: Other", + "readonly": false + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "readonly": false + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "readonly": false + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "readonly": false + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "username", + "readonly": false + }, + { + "name": "field18", + "title": "Account number", + "value": "hederaAccountId", + "readonly": false + } + ], + "idType": "UUID", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0", + "preset": true, + "presetSchema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0" + }, + { + "id": "63aa0736-9fa7-4892-823a-4ccb9aacaf7d", + "tag": "save_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "issue_request", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "1be4a600-f9b4-47e8-9182-cf4cdde0ff29", + "tag": "create_issue_request", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "issue_request", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "f47ff7fb-5ab6-4922-8f0b-54a0751bdf23", + "tag": "issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "f4a20723-df41-4855-a42f-c5da58468430", + "tag": "issue_requests_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "890abca7-faec-48fc-8180-ca7f9c9c86af", + "tag": "issue_requests_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "f178fae2-5301-41f6-90ef-1064fa6ed0d8", + "tag": "issue_by_device", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "ad49b2e1-b70d-428e-bb60-035dd73ebb5c", + "tag": "devices_source_from_filters", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "field": "document.credentialSubject.0.ref", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Status", + "type": "text" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "acf62e74-b3f3-4828-8e35-f7c745294572", + "tag": "token_history_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "1f0869b8-ea2b-437c-9ac9-fa4dc755874b", + "tag": "token_history_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "bbc1e89e-1ef2-4c89-9bf8-7737bae0862d", + "tag": "token_history_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "13c9ed2c-0a61-43ed-a72e-e1d008d03673", + "tag": "token_history_source_filter", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "148d53d1-cd0c-44da-ac71-ba6cbac5cece", + "tag": "devices_source_from_filters2", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id", + "field": "document.verifiableCredential.0.credentialSubject.0.field1" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents", + "onlyOwnDocuments": false + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + } + ] + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + }, + { + "id": "4f1d3a20-4a19-4957-89d3-0e5847fa867d", + "tag": "save_application_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "0b71ab18-c5e0-409c-88cc-c92f42bbe31e", + "tag": "application_rejected", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Rejected", + "description": "Your application was rejected", + "type": "text" + }, + "stopPropagation": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "dde28c1a-d2ac-488c-8930-fffdc4633409", + "tag": "evident_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "551a0f55-5b24-4e09-9ea7-8a7667356b34", + "tag": "approve_application_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "f5b2c737-001f-4c91-85e1-f73fc5c5f504", + "tag": "registrants_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "33295f2e-387b-4692-82e7-c396be00e349", + "tag": "registrants_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5&1.0.0" + }, + { + "id": "55809fd0-61b4-4f61-aeab-b55b87e4c61c", + "tag": "registrants_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#049308d8-d519-427c-bfae-8c77e7671da5&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Legal Name", + "name": "document.credentialSubject.0.field1.field0", + "type": "text" + }, + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Operation", + "name": "option.status", + "type": "text", + "width": "250px", + "bindGroup": "registrants_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_registrant_btn", + "width": "250px", + "bindGroup": "registrants_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "save_application_status(approve)", + "save_application_status(reject)" + ] + }, + { + "id": "29ad0986-0b78-46ac-9b20-21327b64b5f8", + "tag": "approve_registrant_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_application_status(approve)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_application_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Applications" + } + }, + { + "id": "b839fbf9-8242-42f1-bbf6-09af70186715", + "tag": "approve_device_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "0caad883-3411-4d09-b924-ad3b348c9901", + "tag": "approve_devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "97ca41de-29a7-4e8d-abec-eb251273c4c2", + "tag": "approve_devices_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0" + }, + { + "id": "c557a726-8ad4-494d-b6be-920446bbb252", + "tag": "approve_devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#ca220a1e-1622-4ef1-ba10-468eff2b97af&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field3.field0", + "type": "text" + }, + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "approve_devices_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_device_btn", + "width": "250px", + "bindGroup": "approve_devices_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "97314ec6-efa0-4aa4-8888-4ad1c00bf290", + "tag": "approve_device_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_device_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_device_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "2ce44de5-17c7-44fa-881b-daf3c72629f8", + "tag": "save_device_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "stopPropagation": false, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "2f3dced4-04f9-49fb-81b8-ada92064dcae", + "tag": "sign_device_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "actor": "", + "issuer": "policyOwner" + }, + { + "id": "242d938f-4d8d-4b7b-9bf7-1b71d45e4a18", + "tag": "save_copy_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "device(Approved)", + "topicOwner": "owner" + }, + { + "id": "35610541-14f8-49bf-9aec-a6b8a3f59c3d", + "tag": "save_copy_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "device(Approved)", + "dataType": "", + "stopPropagation": true, + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "b57e1090-c13e-4cd7-ba31-ad375ffd1494", + "tag": "save_device_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "stopPropagation": true, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "5a5334b1-f9b9-489d-8d86-6d9af6d77a03", + "tag": "approve_issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "a6b2ed95-7ce2-4212-b64a-647aea6df91c", + "tag": "issue_requests_grid(evident)", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "2c59784d-8ba9-4deb-9d98-d772605aabde", + "tag": "issue_requests_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0" + }, + { + "id": "6a665b70-b53a-4d27-b9be-3a0bb452ddd3", + "tag": "issue_requests_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "issue_requests_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_issue_requests_btn", + "width": "250px", + "bindGroup": "issue_requests_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + }, + { + "id": "82482ff6-e790-4cde-868f-1d59edcd2a9c", + "tag": "approve_issue_requests_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_issue_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_issue_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "1e3888a4-bbd0-43bf-9ae5-6eda5385ef78", + "tag": "mint_events", + "blockType": "interfaceContainerBlock", + "defaultActive": false, + "children": [ + { + "id": "62530dea-346a-488a-8790-bc8eec5a92ae", + "tag": "save_issue_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "issue_request", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "43822cf2-4499-48b6-b878-bab44a2a79eb", + "tag": "sign_issue_by_issuer", + "blockType": "calculateContainerBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "inputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "outputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "inputSchema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0", + "outputSchema": "#fb069289-5bdd-4bba-972a-68b33eca3671&1.0.0" + }, + { + "id": "39e9f22c-4e8b-45ba-8dc8-6777d2f8aa22", + "tag": "save_copy_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "topicOwner": "owner" + }, + { + "id": "ca5ca910-3667-43c3-9640-13b1b7094fa4", + "tag": "save_copy_issue", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minting" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "f234c5d8-7c13-425b-9c17-3345030aa72f", + "tag": "mint_token", + "blockType": "mintDocumentBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "tokenId": "0.0.34804363", + "rule": "field7" + }, + { + "id": "d7fcf0bb-e3b7-4c00-96b2-75a0acc6f1ce", + "tag": "save_issue_status(minted)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minted" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "e3c8cf82-4b74-4639-a35d-3f58597559aa", + "tag": "save_issue_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "entityType": "issue_request", + "dataType": "", + "stopPropagation": true, + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "60a8942a-bfba-46a9-a376-33704fd6eb37", + "tag": "VP", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "1f5f6542-84ff-4add-aa55-53f0184b6f9c", + "tag": "vp_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "41c5240c-49e8-4965-8aef-bd722b5a5bde", + "tag": "vp_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "HASH", + "name": "hash", + "tooltip": "", + "type": "text" + }, + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + }, + { + "title": "TrustChain", + "name": "hash", + "tooltip": "", + "type": "button", + "action": "link", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "trustChainBlock", + "content": "View TrustChain", + "width": "150px" + } + ] + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + }, + { + "id": "84e23b1b-4a4e-4a73-bc75-5fc2d6bcd40d", + "tag": "trust_chain", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "4791aaad-94a8-49fb-aa96-b3a1bc57e584", + "tag": "trustChainBlock", + "blockType": "reportBlock", + "defaultActive": true, + "children": [ + { + "id": "d8d61fd7-eb2f-4f96-9006-64ac60327192", + "tag": "MintTokenItem", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "actionId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Token", + "description": "Token[s] minted." + }, + { + "id": "b3998bcc-bf24-49c3-b7f9-67086b397863", + "tag": "issue_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request(Approved)" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "documentId" + } + ], + "variables": [ + { + "value": "document.credentialSubject.0.id", + "name": "issueId" + }, + { + "name": "registrantId", + "value": "document.credentialSubject.0.field0" + }, + { + "name": "deviceId", + "value": "document.credentialSubject.0.field1" + } + ], + "visible": true, + "iconType": "COMMON", + "title": "Issue Request Review", + "description": "Issue Request processed." + }, + { + "id": "ff24f4fe-2a53-4355-8e1a-922fa6201f32", + "tag": "issue_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.credentialSubject.0.id", + "value": "issueId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Registrant submitted Issue Request to Issuer.", + "title": "Issue Request" + }, + { + "id": "4d882b68-a570-4c1b-bdd2-e8e5773c442a", + "tag": "device_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "type": "equal", + "field": "type", + "value": "device(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Device registration request processed.", + "title": "Device Review" + }, + { + "id": "5b8f5afe-7fbe-44c1-912f-5b9962b96528", + "tag": "device_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "device", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Device Registration", + "description": "Production Facility/Device registration request submitted to Issuer." + }, + { + "id": "ef279ecd-abaa-425e-bb67-1f47a062c326", + "tag": "registrant_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "value", + "field": "type", + "value": "registrant(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application/KYC processed.", + "title": "Application Review" + }, + { + "id": "e7fad57c-6d8b-4ed8-8ece-bdaf2044d4d4", + "tag": "registrant_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application submitted to Issuer.", + "title": "Registrant Application" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "TrustChain" + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + } + ] + }, + "status": "PUBLISH", + "creator": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "owner": "did:hedera:testnet:F9Nhh3jSvVX6sErMuy95WkEr2fqCuWzZFsoq8YWRQdvD;hedera:testnet:tid=0.0.34751333", + "policyRoles": [ + "Registrant" + ], + "policyTopics": [ + { + "name": "Project", + "description": "Project", + "type": "any", + "static": false + } + ], + "topicId": "0.0.34804358", + "instanceTopicId": "0.0.34804466", + "policyTag": "Tag_1652463578256", + "messageId": "1652464053.603998000", + "createDate": "2022-05-13T17:40:11.584Z" + } + ], + "isValid": true, + "errors": { + "blocks": [ + { + "id": "5de4c484-e9fa-4e4e-a3b0-70d945441a34", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "18639325-e036-4773-9eaa-6ccbb965b19d", + "name": "policyRolesBlock", + "errors": [], + "isValid": true + }, + { + "id": "c769991c-af8d-4292-989c-a697cd047f73", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "1ba36c5a-78ac-4081-80f4-7ac8693df3e1", + "name": "interfaceStepBlock", + "errors": [], + "isValid": true + }, + { + "id": "f2c1674d-443f-435f-839f-4325e6ca0698", + "name": "requestVcDocumentBlock", + "errors": [], + "isValid": true + }, + { + "id": "0292bfb4-ebdf-4ff7-a927-ce9fb58925d0", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "fed49259-8ce2-4330-910b-02ee7719b499", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "47dcda17-a066-4713-8b37-3a7e53f30be1", + "name": "informationBlock", + "errors": [], + "isValid": true + }, + { + "id": "27cecf69-1fd4-47d9-b42d-93218e9d1023", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "9e5c60b1-18e3-4770-9771-da9af49811c4", + "name": "reassigningBlock", + "errors": [], + "isValid": true + }, + { + "id": "ee7d2cfa-ec36-46dc-accc-0cad35f270d0", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "47a2c964-23dc-41ce-ae4f-cb4886c7a076", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "4ba98a84-ac13-4f74-b2ec-4cb5be6efae7", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "a4584ad6-fc88-485c-99d4-368b5be76527", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "53e0e097-a9df-4d9a-95e7-8c5ca0acf205", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "a92ef034-74f8-4e80-a7bb-bd40217ce784", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "44f94b84-d19c-4874-adba-e337c63c889c", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "9851be69-140e-458a-b9fa-86610abf8944", + "name": "interfaceStepBlock", + "errors": [], + "isValid": true + }, + { + "id": "86c88ac1-6f89-4e76-9f2b-28ecfb8ae984", + "name": "requestVcDocumentBlock", + "errors": [], + "isValid": true + }, + { + "id": "9929592e-3661-405e-b194-9f0fc25cbec8", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "a798348d-7882-4264-81ca-97d37d60aa43", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "229e0f65-05c0-4af3-b882-cc0638da7654", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "f28a4529-e402-44e7-9fe6-6c2342babe7e", + "name": "interfaceStepBlock", + "errors": [], + "isValid": true + }, + { + "id": "76449598-fdef-4b78-8836-ed986e55aa75", + "name": "requestVcDocumentBlock", + "errors": [], + "isValid": true + }, + { + "id": "60c1ae67-5b4d-4c4b-926f-6afd56e5968f", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "38157ad3-c5e8-4e83-a127-5fc463144b5e", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "5d97928a-7ad0-4d12-8a24-0887d2c462fa", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "5842e60f-ffcf-4cde-bb7c-d0a7d564b58b", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "148d8640-91b6-4453-84a0-88410554e760", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "de8f42d5-6901-441f-9d6f-f7d10ae9fa0f", + "name": "filtersAddon", + "errors": [], + "isValid": true + }, + { + "id": "8063ccbb-3328-490f-ae92-fd773e372e08", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "3da2bbb7-0c4a-4ec9-8c38-b217af2da35b", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "2eaa8a53-0379-4479-a53f-7b397b9b41d8", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "a9abb318-30b3-4b53-bd19-292047b0935b", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "962714b7-8bb5-4958-841a-6b370cfe1192", + "name": "filtersAddon", + "errors": [], + "isValid": true + }, + { + "id": "8b5a74e6-fb37-432d-9223-e89065dca7e5", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "ba6926b1-be6d-46a0-8986-c155b9865331", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "3941044d-d593-4246-b7f7-20e53057e711", + "name": "informationBlock", + "errors": [], + "isValid": true + }, + { + "id": "550b6cc0-35b5-4e81-bfbb-496ffc78e621", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "d1edace7-9ec6-4bc0-9bf0-acaded28fe10", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "869280f7-626a-4e5e-8c88-6d2d14ddbc88", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "283a4eee-01fe-4501-b6df-33cae2c2fd68", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "c4a0dc23-d30c-44f2-95c1-bb46be8cfedb", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "92365a5c-d7bc-4985-b425-cf1340a4f1c7", + "name": "interfaceActionBlock", + "errors": [], + "isValid": true + }, + { + "id": "584752e1-d0bb-4b21-b183-3690207bbdb2", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "888cc08a-9348-41cf-a8fd-365401acf40e", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "8b0438fd-32e3-4666-bdee-54ec071789d3", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "bda94def-d1ba-4fa1-b03a-7c7035a12df5", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "5404a5bf-32d6-483e-8cce-f3ed344eaab4", + "name": "interfaceActionBlock", + "errors": [], + "isValid": true + }, + { + "id": "0495a898-4ae3-4ee1-bf89-1b7bdec3d11b", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "038c7fbc-38cc-4bc5-9600-77594723819e", + "name": "reassigningBlock", + "errors": [], + "isValid": true + }, + { + "id": "9ebf31d2-4ff2-4048-b610-7db47b425e0e", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "e0fa120a-48d0-4e29-a5aa-c5645e997ea2", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "0e082400-1b0f-4229-830f-1e03b5767e17", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "0df2fd8c-1614-4a07-94b1-870e2638e78d", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "5197e08f-0cbe-4ded-a0c0-4657a8ee1c3f", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "499c9c18-2375-4a40-a460-92b8d8f92e96", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "6d352c31-5602-486c-bd35-ef35de6b87ee", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "02f54956-6dd8-4755-aa52-b08674774be9", + "name": "interfaceActionBlock", + "errors": [], + "isValid": true + }, + { + "id": "c272b91f-b2b9-4e52-bd80-c84505d77770", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "dca3ca61-0c75-4530-be9e-847e5db8c251", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "7055730e-0f81-426d-ad3a-032e2d4fc54f", + "name": "calculateContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "739a2a05-ec36-4b1c-b27e-368219e8dd7f", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "cad6e6c9-2408-40a8-9c9f-ab19682d8998", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "6ca507d0-7512-4578-85c5-a85744e8f0ac", + "name": "mintDocumentBlock", + "errors": [], + "isValid": true + }, + { + "id": "14ff06fa-9c76-4468-b873-c59d751b0029", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "54e33f31-76b0-4e7d-ac60-af515c9c22be", + "name": "sendToGuardianBlock", + "errors": [], + "isValid": true + }, + { + "id": "872d5b8f-a8c6-4e94-a24a-ab3f35762e8c", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "0bdac0af-6539-4395-b365-1e8187580a46", + "name": "interfaceDocumentsSourceBlock", + "errors": [], + "isValid": true + }, + { + "id": "d64e68d9-f396-4817-bc38-89def589f582", + "name": "documentsSourceAddon", + "errors": [], + "isValid": true + }, + { + "id": "837286ed-4931-4245-98b5-2365b2aa1b5f", + "name": "interfaceContainerBlock", + "errors": [], + "isValid": true + }, + { + "id": "7bc21e88-af74-48d7-8722-859e06dcdc2c", + "name": "reportBlock", + "errors": [], + "isValid": true + }, + { + "id": "61cec38a-734e-4dbf-a93f-213be5d3e0a2", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "191975eb-42b2-4454-97c4-ae6a37d9b62c", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "6c9d4aca-ee28-4b66-81d0-db6feec7b458", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "01d36d6f-da44-416c-87af-82512f920795", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "9e404222-5247-4923-9a1e-293fad6619f8", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "9da21b8a-3018-4b91-8b34-b293d9d4ec53", + "name": "reportItemBlock", + "errors": [], + "isValid": true + }, + { + "id": "d01cb7b3-1b8f-46ba-9e06-0c34cedfeb2e", + "name": "reportItemBlock", + "errors": [], + "isValid": true + } + ] + } +} +``` +{% endswagger-response %} +{% endswagger %} + +### Tokens + +#### Get Tokens + +{% swagger method="get" path="" baseUrl="/tokens" summary="Getting Tokens Details" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + + "id": "627e97ea0f12a18fef5f1d58", + "tokenId": "0.0.34804363", + "tokenName": "iRec Token", + "tokenSymbol": "iRec", + "tokenType": "non-fungible", + "decimals": 0, + "policies": [ + "iRec_2_1650456840748_1652463611568 (1.0.0)" + ], + "associated": false, + "balance": null, + "hBarBalance": null, + "frozen": null, + "kyc": null +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Associate + +{% swagger method="put" path="" baseUrl="/tokens/{token_Id}/associate" summary="Associating the Token" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Grant KYC + +{% swagger method="put" path="{userUsername}/grantKYC" baseUrl="/tokens/{tokenId}/" summary="Granting KYC" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "tokenId": "0.0.34804363", + "policies": null, + "associated": true, + "balance": "0", + "hBarBalance": "29.49376516 ℏ", + "frozen": false, + "kyc": true +} +``` +{% endswagger-response %} +{% endswagger %} + +### Blocks + +#### Choose Role uuid + +{% swagger method="get" path="" baseUrl="/policies/{{policyId}}/tag/choose_role" summary="Choosing Role" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "4bee425d-dfba-451a-b47d-ac945aeddc3e" +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Choose Role + +{% swagger method="post" path="" baseUrl="/policies/{{policyId}}/blocks/{{chooseRoleBlockUUID}}" summary="Choosing role as Registrant" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "6282755493e1d09322c4ed13", + "uuid": "759df7c0-b4e9-4adf-9c63-62939c62d1f4", + "name": "iRec_2_1650456840748_1652716884953", + "version": "2.0.2", + "description": "iRec Description", + "topicDescription": "iRec Description", + "config": { + "blockType": "interfaceContainerBlock", + "permissions": [ + "ANY_ROLE" + ], + "id": "a94e8570-0d0e-4214-9b2b-5695bc46fbb2", + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "children": [ + { + "id": "4bee425d-dfba-451a-b47d-ac945aeddc3e", + "tag": "choose_role", + "blockType": "policyRolesBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "NO_ROLE" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Registration", + "description": "Choose a role" + }, + "roles": [ + "Registrant" + ] + }, + { + "id": "1e4cfa36-fe35-4e31-ae5b-1d979c65f031", + "tag": "registrants_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "4148dd76-cdab-471e-8e88-a7a912e819c1", + "tag": "registrants_workflow_steps", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "c6a4db28-6a4f-4137-9b42-530783443147", + "tag": "create_application", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "page", + "title": "Registrant Application" + }, + "presetFields": [], + "schema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "idType": "OWNER" + }, + { + "id": "4370496c-560f-48f7-b435-15e5e9fc8a77", + "tag": "save_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "entityType": "registrant", + "topic": "Project", + "dataSource": "hedera", + "documentType": "vc", + "topicOwner": "user" + }, + { + "id": "fd4ef1cf-26ce-432e-b425-50d4329e5f5e", + "tag": "create_application(db)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "09d2472b-cd30-4339-9a01-57c5c17029d1", + "tag": "wait_for_approve", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "description": "The page will refresh automatically once the application is approved.", + "type": "text", + "title": "Submitted for Approval" + }, + "stopPropagation": true + }, + { + "id": "313042d7-95c0-4ed2-b5ea-bf77fec29ad2", + "tag": "save_application_status(approve)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "916e7f10-2c65-43b2-86a7-494c78963e87", + "tag": "sign_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "issuer": "policyOwner", + "actor": "owner" + }, + { + "id": "0a31efea-bfb9-47de-a908-d9201ca8e579", + "tag": "save_copy_application(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "registrant(Approved)", + "topicOwner": "owner" + }, + { + "id": "d907660e-9834-42a1-a077-e8e38332b6e4", + "tag": "save_copy_application", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "dataType": "", + "entityType": "registrant(Approved)", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "fd215b72-33a0-47fd-84fa-d846f3d34040", + "tag": "registrants_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "be83cf5b-c6ca-4065-8eca-1a8aee328a4c", + "tag": "devices_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "81dcdea7-8a28-49df-8a55-78540e2d501c", + "tag": "devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "3fa477e2-e637-4b70-b762-cf52903f26ef", + "tag": "devices_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0", + "dataType": "vc-documents", + "onlyOwnDocuments": true + }, + { + "id": "d731215b-187d-42d4-8e62-0267d5b0f07a", + "tag": "devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device(Approved)", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "title": "Issue Request", + "name": "option.status", + "type": "text", + "bindGroup": "devices_source", + "width": "150px" + }, + { + "title": "Issue Request", + "name": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "create_issue_request_form", + "width": "150px", + "bindGroup": "devices_source(approved)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "create_issue_request", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "e2c354d5-9532-4b97-97a4-7c9262e84215", + "tag": "new_device", + "blockType": "interfaceStepBlock", + "defaultActive": true, + "children": [ + { + "id": "bb8ddf01-e056-4632-8aa1-7c1c8aa5a1ee", + "tag": "create_device_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [ + { + "id": "3b55a17c-1df8-4684-978b-7f09bc18467f", + "tag": "current_registrant", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant(Approved)", + "field": "type", + "type": "equal" + } + ], + "onlyOwnDocuments": true, + "schema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "dataType": "vc-documents" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create New Device", + "dialogContent": "Device Registration" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "id", + "readonly": false + }, + { + "name": "field1", + "title": "Date", + "readonly": false + }, + { + "name": "field2", + "title": "Is the Registrant also the owner of the Device? (provide evidence) ", + "readonly": false + }, + { + "name": "field3", + "title": "Registrant Details", + "value": "field2", + "readonly": false + }, + { + "name": "field4", + "title": "Production Device Details", + "readonly": false + }, + { + "name": "field5", + "title": "Energy Sources", + "readonly": false + } + ], + "idType": "DID", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0", + "preset": true, + "presetSchema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0" + }, + { + "id": "711119c3-340f-40ef-aadf-0c6425f5d29a", + "tag": "save_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "device", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "28400c06-b6fd-4ef9-aa1f-ed33eda0b11d", + "tag": "create_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "entityType": "device", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + }, + { + "id": "3f40645d-ce7a-41c0-8983-f654adf88ba9", + "tag": "new_issue_request", + "blockType": "interfaceStepBlock", + "defaultActive": false, + "children": [ + { + "id": "81a1c852-b8d6-442d-bbf1-e2547e76935f", + "tag": "create_issue_request_form", + "blockType": "requestVcDocumentBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "dialog", + "content": "Create Issue Request", + "dialogContent": "New Issue Request", + "buttonClass": "link" + }, + "presetFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0", + "readonly": false + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "id", + "readonly": false + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field3", + "readonly": false + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field4", + "readonly": false + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "readonly": false + }, + { + "name": "field5", + "title": "Last registration date", + "readonly": false + }, + { + "name": "field6", + "title": "Production Period Start Date", + "readonly": false + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "readonly": false + }, + { + "name": "field8", + "title": "Production Period End Date", + "readonly": false + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "readonly": false + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "readonly": false + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "readonly": false + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "readonly": false + }, + { + "name": "field13", + "title": "Type d: Other", + "readonly": false + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "readonly": false + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "readonly": false + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "readonly": false + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "username", + "readonly": false + }, + { + "name": "field18", + "title": "Account number", + "value": "hederaAccountId", + "readonly": false + } + ], + "idType": "UUID", + "schema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0", + "preset": true, + "presetSchema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0" + }, + { + "id": "0081c692-5a1d-4f40-8247-8ab995b3e775", + "tag": "save_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataType": "", + "topic": "Project", + "entityType": "issue_request", + "dataSource": "hedera", + "documentType": "vc" + }, + { + "id": "0ee66008-3bfc-4c48-ad30-9c28063e06ab", + "tag": "create_issue_request", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Waiting for approval" + } + ], + "dataType": "", + "entityType": "issue_request", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + }, + "cyclic": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "5cf0c0cd-1ab3-4383-82d3-dde2d853a902", + "tag": "issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "849d0cff-a21e-45ef-ab42-b90934b76c69", + "tag": "issue_requests_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "625894be-8460-435e-bc41-eddd24ef0c5a", + "tag": "issue_requests_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "60229204-bbc3-497d-8190-080d48036e3e", + "tag": "issue_by_device", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "0fbf0df1-4bd7-4663-8db0-58e61feca937", + "tag": "devices_source_from_filters", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "field": "document.credentialSubject.0.ref", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Status", + "type": "text" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "d77bce9e-38b2-447d-9070-ede109353d1d", + "tag": "token_history_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "49c1fd87-8374-4ceb-b441-84b8c581d243", + "tag": "token_history_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "06337d1a-b428-4e15-949c-16c039ea4c54", + "tag": "token_history_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [ + { + "id": "d24e11d3-2b7b-4c99-9a56-79e8c4a93e2c", + "tag": "token_history_source_filter", + "blockType": "filtersAddon", + "defaultActive": true, + "children": [ + { + "id": "0a773064-3b43-4b3f-b2f1-59cad2dd8467", + "tag": "devices_source_from_filters2", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Approved", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0", + "onlyOwnDocuments": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [], + "content": "Device" + }, + "type": "dropdown", + "optionName": "document.credentialSubject.0.field3.field0", + "optionValue": "document.credentialSubject.0.id", + "field": "document.verifiableCredential.0.credentialSubject.0.field1" + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents", + "onlyOwnDocuments": false + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + } + ] + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + }, + { + "id": "b50e5c11-54ab-4212-8eb7-a2ee54fe4df9", + "tag": "save_application_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "dataType": "", + "entityType": "registrant", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "54de67e7-ca43-4e8f-b2a6-2d52170bae0d", + "tag": "application_rejected", + "blockType": "informationBlock", + "defaultActive": true, + "children": [], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "title": "Rejected", + "description": "Your application was rejected", + "type": "text" + }, + "stopPropagation": true + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + } + ], + "permissions": [ + "Registrant" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "35a2c9a9-8f7c-4d61-a8d3-0d7b815883eb", + "tag": "evident_workflow", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "12288e3d-68a6-4e6c-bc34-683620041ce1", + "tag": "approve_application_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "f46af5f5-e0f2-4ede-bcd2-8e1a55bd1fca", + "tag": "registrants_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "bb1b84e4-3524-4849-a646-cca3623b0d75", + "tag": "registrants_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0" + }, + { + "id": "1adf6b92-a184-43f4-99ab-3113fee26fa1", + "tag": "registrants_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "registrant", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Legal Name", + "name": "document.credentialSubject.0.field1.field0", + "type": "text" + }, + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Operation", + "name": "option.status", + "type": "text", + "width": "250px", + "bindGroup": "registrants_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_registrant_btn", + "width": "250px", + "bindGroup": "registrants_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "save_application_status(approve)", + "save_application_status(reject)" + ] + }, + { + "id": "c2eef66b-ec9f-42c5-99b2-430625c49e88", + "tag": "approve_registrant_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_application_status(approve)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_application_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Applications" + } + }, + { + "id": "96e1f20a-6e3e-46a7-9dcf-49f8cf4f7b59", + "tag": "approve_device_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "5d570f5b-a533-4481-8602-bb8355b50b46", + "tag": "approve_devices_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "fa2732a1-1e98-4852-91b7-43ec49c1c10c", + "tag": "approve_devices_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0" + }, + { + "id": "4a8cf9d1-6df8-45eb-9e7d-99c6455283c8", + "tag": "approve_devices_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "device", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#0bb392cd-17ee-43e7-b4fd-85fd392dae24&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field3.field0", + "type": "text" + }, + { + "title": "Device Name", + "name": "document.credentialSubject.0.field4.field0", + "type": "text" + }, + { + "title": "Address", + "name": "document.credentialSubject.0.field4.field1", + "type": "text" + }, + { + "title": "Longitude", + "name": "document.credentialSubject.0.field4.field4", + "type": "text" + }, + { + "title": "Latitude", + "name": "document.credentialSubject.0.field4.field5", + "type": "text" + }, + { + "title": "Capacity (kW)", + "name": "document.credentialSubject.0.field4.field7", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "approve_devices_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_device_btn", + "width": "250px", + "bindGroup": "approve_devices_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_device", + "save_device_status(approved)", + "save_device_status(reject)" + ] + }, + { + "id": "12b8bd1d-8429-4917-90f4-cdfcced32d46", + "tag": "approve_device_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_device_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_device_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "ba063b00-e9b4-400c-b509-804d572397e2", + "tag": "save_device_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "stopPropagation": false, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "369549d1-9d85-4b15-90b5-6ed153ffdd91", + "tag": "sign_device_by_issuer", + "blockType": "reassigningBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "actor": "", + "issuer": "policyOwner" + }, + { + "id": "a4e3cd8b-92d2-4c22-bfbb-92bd496d0d75", + "tag": "save_copy_device(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "entityType": "device(Approved)", + "topicOwner": "owner" + }, + { + "id": "a36c2d1c-9572-4cb8-8b63-8994cc0697bd", + "tag": "save_copy_device", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "device(Approved)", + "dataType": "", + "stopPropagation": true, + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "4e506ada-30ea-4976-b8b4-f6347b4e8464", + "tag": "save_device_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "stopPropagation": true, + "dataType": "", + "entityType": "device", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Devices" + } + }, + { + "id": "250e8b46-463d-4382-bff3-0d28e353ef62", + "tag": "approve_issue_requests_page", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "965abb1d-f2c4-4839-9bbe-97b166e6a563", + "tag": "issue_requests_grid(evident)", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "42bed28d-a657-479c-aac0-72fd3a15ccf0", + "tag": "issue_requests_source(need_approve)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0" + }, + { + "id": "1e98a1a2-8885-4148-a55d-1e0139787f83", + "tag": "issue_requests_source(approved)", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "Waiting for approval", + "field": "option.status", + "type": "not_equal" + }, + { + "value": "issue_request", + "field": "type", + "type": "equal" + } + ], + "dataType": "vc-documents", + "schema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Production Period Start Date", + "name": "document.credentialSubject.0.field6", + "type": "text" + }, + { + "title": "Production Period End Date", + "name": "document.credentialSubject.0.field8", + "type": "text" + }, + { + "title": "Total kWh Produced in this period", + "name": "document.credentialSubject.0.field7", + "type": "text" + }, + { + "title": "Date", + "name": "document.issuanceDate", + "type": "text" + }, + { + "name": "option.status", + "title": "Operation", + "type": "text", + "width": "250px", + "bindGroup": "issue_requests_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_issue_requests_btn", + "width": "250px", + "bindGroup": "issue_requests_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] + }, + "dependencies": [ + "create_issue_request", + "save_issue_status(minted)", + "save_issue_status(minting)", + "save_issue_status(reject)" + ] + }, + { + "id": "5216642b-1df2-4bc2-93a8-2c019885d53b", + "tag": "approve_issue_requests_btn", + "blockType": "interfaceActionBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "options": [ + { + "title": "", + "name": "Approve", + "tooltip": "", + "type": "text", + "value": "Approved", + "uiClass": "btn-approve", + "bindBlock": "save_issue_status(approved)" + }, + { + "title": "", + "name": "Reject", + "tooltip": "", + "type": "text", + "value": "Rejected", + "uiClass": "btn-reject", + "bindBlock": "save_issue_status(reject)" + } + ] + }, + "type": "selector", + "field": "option.status" + }, + { + "id": "e78af134-673c-4ab1-91b4-a7d3f859a1e1", + "tag": "mint_events", + "blockType": "interfaceContainerBlock", + "defaultActive": false, + "children": [ + { + "id": "07d04683-db3e-43df-899c-e7a9e2527af6", + "tag": "save_issue_status(approved)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Approved" + } + ], + "entityType": "issue_request", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "8f1b240f-e03f-434a-b84d-b385c59d0857", + "tag": "sign_issue_by_issuer", + "blockType": "calculateContainerBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "inputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "outputFields": [ + { + "name": "field0", + "title": "Registrant Id", + "value": "field0" + }, + { + "name": "field1", + "title": "Production Device/Production Group Id", + "value": "field1" + }, + { + "name": "field2", + "title": "Registrant Details", + "value": "field2" + }, + { + "name": "field3", + "title": "Production Device/Production Group", + "value": "field3" + }, + { + "name": "field4", + "title": "Labelling scheme(s)", + "value": "field4" + }, + { + "name": "field5", + "title": "Last registration date", + "value": "field5" + }, + { + "name": "field6", + "title": "Production Period Start Date", + "value": "field6" + }, + { + "name": "field7", + "title": "Total kWh Produced in this period", + "value": "field7" + }, + { + "name": "field8", + "title": "Production Period End Date", + "value": "field8" + }, + { + "name": "field9", + "title": "Percentage of eligible total applied for", + "value": "field9" + }, + { + "name": "field10", + "title": "Type a: Settlement Metering data", + "value": "field10" + }, + { + "name": "field11", + "title": "Type b: Non-settlement Metering data", + "value": "field11" + }, + { + "name": "field12", + "title": "Type c: Measured Volume Transfer documentation", + "value": "field12" + }, + { + "name": "field13", + "title": "Type d: Other", + "value": "field13" + }, + { + "name": "field14", + "title": "Is the production of this electricity counted towards a national, sub-national or regulatory target?", + "value": "field14" + }, + { + "name": "field15", + "title": "Is any of this production subject to a public consumption obligation?", + "value": "field15" + }, + { + "name": "field16", + "title": "Do you retain the right to obtain emissions reduction certificates or carbon offsets for the energy nominated in this Issue Request?", + "value": "field16" + }, + { + "name": "field17", + "title": "I-REC Participant name", + "value": "field17" + }, + { + "name": "field18", + "title": "Account number", + "value": "field18" + } + ], + "inputSchema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0", + "outputSchema": "#17d892a5-4d98-43e1-aa78-e42ffc9ec64d&1.0.0" + }, + { + "id": "ca5480c9-09eb-439c-9a10-c0c8f94ebb48", + "tag": "save_copy_issue(hedera)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [], + "dataSource": "hedera", + "documentType": "vc", + "topic": "Project", + "topicOwner": "owner" + }, + { + "id": "ea14d0fc-3a5d-44c6-b10b-924cc9747f6e", + "tag": "save_copy_issue", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minting" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "forceNew": true, + "dataSource": "database", + "documentType": "vc" + }, + { + "id": "37c31f88-2a51-4260-944f-12429d0094bb", + "tag": "mint_token", + "blockType": "mintDocumentBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "tokenId": "0.0.34824585", + "rule": "field7" + }, + { + "id": "acccb5c8-30bf-422f-addb-6fa3e63e30a6", + "tag": "save_issue_status(minted)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Minted" + } + ], + "entityType": "issue_request(Approved)", + "dataType": "", + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank" + } + }, + { + "id": "1b1fd6e3-ee03-40d0-b2f7-98fe8b5443e0", + "tag": "save_issue_status(reject)", + "blockType": "sendToGuardianBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": {}, + "options": [ + { + "name": "status", + "value": "Rejected" + } + ], + "entityType": "issue_request", + "dataType": "", + "stopPropagation": true, + "dataSource": "database", + "documentType": "vc" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Issue Requests" + } + }, + { + "id": "eb1825cc-e364-4af3-9fb7-a346050e271c", + "tag": "VP", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "d6701c82-6426-4556-b0f4-d0e574611d87", + "tag": "vp_grid", + "blockType": "interfaceDocumentsSourceBlock", + "defaultActive": true, + "children": [ + { + "id": "dc7e3e56-1fee-4d05-8592-d8578c7cdc29", + "tag": "vp_source", + "blockType": "documentsSourceAddon", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [], + "dataType": "vp-documents" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "fields": [ + { + "title": "HASH", + "name": "hash", + "tooltip": "", + "type": "text" + }, + { + "title": "Date", + "name": "document.verifiableCredential.1.credentialSubject.0.date", + "tooltip": "", + "type": "text" + }, + { + "title": "Token Id", + "name": "document.verifiableCredential.1.credentialSubject.0.tokenId", + "tooltip": "", + "type": "text" + }, + { + "title": "Serials", + "name": "document.verifiableCredential.1.credentialSubject.0.serials", + "tooltip": "", + "type": "text" + }, + { + "title": "TrustChain", + "name": "hash", + "tooltip": "", + "type": "button", + "action": "link", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "trustChainBlock", + "content": "View TrustChain", + "width": "150px" + } + ] + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "Token History" + } + }, + { + "id": "415dcbaf-8f1c-4be1-97ae-2aa7ab94add5", + "tag": "trust_chain", + "blockType": "interfaceContainerBlock", + "defaultActive": true, + "children": [ + { + "id": "fefdd1de-fece-498d-a558-ee0be5c6e2d8", + "tag": "trustChainBlock", + "blockType": "reportBlock", + "defaultActive": true, + "children": [ + { + "id": "a5f59886-79ff-47ec-9556-d3f58fe5155c", + "tag": "MintTokenItem", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "actionId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Token", + "description": "Token[s] minted." + }, + { + "id": "802f59dc-5d98-41e4-8eeb-18ee4e674c1d", + "tag": "issue_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request(Approved)" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.id", + "value": "documentId" + } + ], + "variables": [ + { + "value": "document.credentialSubject.0.id", + "name": "issueId" + }, + { + "name": "registrantId", + "value": "document.credentialSubject.0.field0" + }, + { + "name": "deviceId", + "value": "document.credentialSubject.0.field1" + } + ], + "visible": true, + "iconType": "COMMON", + "title": "Issue Request Review", + "description": "Issue Request processed." + }, + { + "id": "f1083902-3216-4ad1-81ac-c35b0bf5b567", + "tag": "issue_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "field": "type", + "type": "equal", + "value": "issue_request" + }, + { + "type": "equal", + "typeValue": "variable", + "field": "document.credentialSubject.0.id", + "value": "issueId" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Registrant submitted Issue Request to Issuer.", + "title": "Issue Request" + }, + { + "id": "2b2aef32-1322-4ee5-8ce3-c2a0fc000622", + "tag": "device_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "typeValue": "value", + "type": "equal", + "field": "type", + "value": "device(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Device registration request processed.", + "title": "Device Review" + }, + { + "id": "6cd69397-8c98-476b-9b80-484c5eebeb0a", + "tag": "device_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "device", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "deviceId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "title": "Device Registration", + "description": "Production Facility/Device registration request submitted to Issuer." + }, + { + "id": "2aeabc7a-5f87-44b2-8f3c-0efa0301f0a0", + "tag": "registrant_report(approved)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "type": "equal", + "typeValue": "value", + "field": "type", + "value": "registrant(Approved)" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application/KYC processed.", + "title": "Application Review" + }, + { + "id": "a93f46ea-cce0-4218-963a-3d5b634abe2a", + "tag": "registrant_report(submit)", + "blockType": "reportItemBlock", + "defaultActive": false, + "children": [], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "filters": [ + { + "value": "registrant", + "field": "type", + "type": "equal", + "typeValue": "value" + }, + { + "field": "document.credentialSubject.0.id", + "value": "registrantId", + "type": "equal", + "typeValue": "variable" + } + ], + "variables": [], + "visible": true, + "iconType": "COMMON", + "description": "Application submitted to Issuer.", + "title": "Registrant Application" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action" + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "blank", + "title": "TrustChain" + } + } + ], + "permissions": [ + "OWNER" + ], + "onErrorAction": "no-action", + "uiMetaData": { + "type": "tabs" + } + } + ] + }, + "status": "PUBLISH", + "creator": "did:hedera:testnet:G8S2SYNkuZq8R2MBRuBUagRSb4oucbZipJk8XADwe1T7;hedera:testnet:tid=0.0.34824275", + "owner": "did:hedera:testnet:G8S2SYNkuZq8R2MBRuBUagRSb4oucbZipJk8XADwe1T7;hedera:testnet:tid=0.0.34824275", + "policyRoles": [ + "Registrant" + ], + "policyTopics": [ + { + "name": "Project", + "description": "Project", + "type": "any", + "static": false + } + ], + "registeredUsers": { + "did:hedera:testnet:2naXnVQ86KZySwwWfMzh6Y9Tfj6mCHj5hY8sjLQvxP3B;hedera:testnet:tid=0.0.34824275": "Registrant" + }, + "topicId": "0.0.34824582", + "instanceTopicId": "0.0.34824602", + "policyTag": "Tag_1652716862083", + "messageId": "1652716935.214194999", + "createDate": "2022-05-16T16:01:24.955Z" +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Create Application uuid + +{% swagger method="get" path="" baseUrl="/policies/{{policyId}}/tag/create_application" summary="Displaying Application uuid" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "c6a4db28-6a4f-4137-9b42-530783443147" +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Get Registrant Schema + +{% swagger method="get" path="" baseUrl="policies/{{policyId}}/blocks/{{create_application_uuid}}" summary="Displaying Registrant Schema uuid" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "c6a4db28-6a4f-4137-9b42-530783443147", + "blockType": "requestVcDocumentBlock", + "schema": { + "userDID": null, + "id": "6282755193e1d09322c4ed10", + "uuid": "732d99d8-b254-4aa7-8bb4-e78f15212892", + "hash": "", + "name": "I-REC Registrant & Participant App", + "description": "I-REC Registrant & Participant App", + "entity": "VC", + "status": "PUBLISHED", + "readonly": false, + "version": "1.0.0", + "creator": "did:hedera:testnet:G8S2SYNkuZq8R2MBRuBUagRSb4oucbZipJk8XADwe1T7;hedera:testnet:tid=0.0.34824275", + "owner": "did:hedera:testnet:G8S2SYNkuZq8R2MBRuBUagRSb4oucbZipJk8XADwe1T7;hedera:testnet:tid=0.0.34824275", + "topicId": "0.0.34824582", + "messageId": "1652716919.907860000", + "documentURL": "https://ipfs.io/ipfs/bafkreibaheup25wqaa6thx3b3m5t36w3jfh4t5np73k7dzlfm5c4crnaoa", + "contextURL": "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i", + "iri": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "document": { + "$id": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "$comment": "{\"term\": \"732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0\", \"@id\": \"https://ipfs.io/ipfs/bafkreiejsgxjj4ntamvgattviac5vtf5rtpvnvmojk444lyawutwsfnvwi#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0\"}", + "title": "I-REC Registrant & Participant App", + "description": "I-REC Registrant & Participant App", + "type": "object", + "properties": { + "@context": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "type": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "id": { + "type": "string", + "readOnly": true + }, + "field0": { + "title": "Date", + "description": "Date", + "readOnly": false, + "$comment": "{\"term\": \"field0\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string", + "format": "date" + }, + "field1": { + "title": "Applicant Details", + "description": "Applicant Details", + "readOnly": false, + "$comment": "{\"term\": \"field1\", \"@id\": \"https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#6d009939-3c53-44fd-8a0c-c9d98472ff09\"}", + "$ref": "#6d009939-3c53-44fd-8a0c-c9d98472ff09" + }, + "field2": { + "title": "Primary Contact Details", + "description": "Primary Contact Details", + "readOnly": false, + "$comment": "{\"term\": \"field2\", \"@id\": \"https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#e0d61835-0491-4df8-9d48-21e961a7916f\"}", + "$ref": "#e0d61835-0491-4df8-9d48-21e961a7916f" + }, + "field3": { + "title": "Lead User Details\t", + "description": "Lead User Details\t", + "readOnly": false, + "$comment": "{\"term\": \"field3\", \"@id\": \"https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#66b7a5fe-2c17-422d-9744-b4b55c2174b9\"}", + "$ref": "#66b7a5fe-2c17-422d-9744-b4b55c2174b9" + }, + "policyId": { + "title": "policyId", + "description": "policyId", + "readOnly": true, + "$comment": "{\"term\": \"policyId\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "ref": { + "title": "ref", + "description": "ref", + "readOnly": true, + "$comment": "{\"term\": \"ref\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + } + }, + "required": [ + "@context", + "type", + "field1", + "field2", + "field3", + "policyId" + ], + "additionalProperties": false, + "$defs": { + "#6d009939-3c53-44fd-8a0c-c9d98472ff09": { + "$id": "#6d009939-3c53-44fd-8a0c-c9d98472ff09", + "$comment": "{\"term\": \"6d009939-3c53-44fd-8a0c-c9d98472ff09\", \"@id\": \"https://ipfs.io/ipfs/bafkreihe55hxacf32sxuybe3s3otblhfs3y5qlk3lccjvksh7kncwf6ura#6d009939-3c53-44fd-8a0c-c9d98472ff09\"}", + "title": "Applicant Details", + "description": " Applicant Details", + "type": "object", + "properties": { + "@context": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "type": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "id": { + "type": "string", + "readOnly": true + }, + "field0": { + "title": "Applicant Legal Name", + "description": "Applicant Legal Name", + "readOnly": false, + "$comment": "{\"term\": \"field0\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field1": { + "title": "Registered address line 1", + "description": "Registered address line 1", + "readOnly": false, + "$comment": "{\"term\": \"field1\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field2": { + "title": "Registered address line 2", + "description": "Registered address line 2", + "readOnly": false, + "$comment": "{\"term\": \"field2\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field3": { + "title": "Registered address line 3", + "description": "Registered address line 3", + "readOnly": false, + "$comment": "{\"term\": \"field3\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field4": { + "title": "Postal (ZIP) code", + "description": "Postal (ZIP) code", + "readOnly": false, + "$comment": "{\"term\": \"field4\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field5": { + "title": "Country", + "description": "Country", + "readOnly": false, + "$comment": "{\"term\": \"field5\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field6": { + "title": "Legal Status", + "description": "Legal Status", + "readOnly": false, + "$comment": "{\"term\": \"field6\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field7": { + "title": "Country of company registration/private residence", + "description": "Country of company registration/private residence", + "readOnly": false, + "$comment": "{\"term\": \"field7\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field8": { + "title": "Corporate registration number/passport number", + "description": "Corporate registration number/passport number", + "readOnly": false, + "$comment": "{\"term\": \"field8\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field9": { + "title": "VAT number", + "description": "VAT number", + "readOnly": false, + "$comment": "{\"term\": \"field9\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field10": { + "title": "Website URL", + "description": "Website URL", + "readOnly": false, + "$comment": "{\"term\": \"field10\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field11": { + "title": "Main business (e.g. food retailer)", + "description": "Main business (e.g. food retailer)", + "readOnly": false, + "$comment": "{\"term\": \"field11\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field12": { + "title": "Year of registration", + "description": "Year of registration", + "readOnly": false, + "$comment": "{\"term\": \"field12\", \"@id\": \"https://www.schema.org/text\"}", + "type": "integer" + }, + "field13": { + "title": "Approximate number of employees", + "description": "Approximate number of employees", + "readOnly": false, + "$comment": "{\"term\": \"field13\", \"@id\": \"https://www.schema.org/text\"}", + "type": "integer" + }, + "field14": { + "title": "Name of the Chief Executive Officer/General Manager", + "description": "Name of the Chief Executive Officer/General Manager", + "readOnly": false, + "$comment": "{\"term\": \"field14\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field15": { + "title": "Chief Executive Officer/General Manager passport number", + "description": "Chief Executive Officer/General Manager passport number", + "readOnly": false, + "$comment": "{\"term\": \"field15\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field16": { + "title": "Please state in which countries the organization is active", + "description": "Please state in which countries the organization is active", + "readOnly": false, + "$comment": "{\"term\": \"field16\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field17": { + "title": "Please list the main (>10%) shareholders ", + "description": "Please list the main (>10%) shareholders ", + "readOnly": false, + "$comment": "{\"term\": \"field17\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field18": { + "title": "Balance sheet total for last financial year (in USD)", + "description": "Balance sheet total for last financial year (in USD)", + "readOnly": false, + "$comment": "{\"term\": \"field18\", \"@id\": \"https://www.schema.org/text\"}", + "type": "number" + }, + "field19": { + "title": "Email address for Accounts Department", + "description": "Email address for Accounts Department", + "readOnly": false, + "$comment": "{\"term\": \"field19\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string", + "format": "email" + } + }, + "required": [ + "@context", + "type" + ], + "additionalProperties": false + }, + "#e0d61835-0491-4df8-9d48-21e961a7916f": { + "$id": "#e0d61835-0491-4df8-9d48-21e961a7916f", + "$comment": "{\"term\": \"e0d61835-0491-4df8-9d48-21e961a7916f\", \"@id\": \"https://ipfs.io/ipfs/bafkreidwms3pistbvq472d3zkhpll7eth7azpwmftour4xmzrntvibhk2u#e0d61835-0491-4df8-9d48-21e961a7916f\"}", + "title": "Contact Details", + "description": "Contact Details", + "type": "object", + "properties": { + "@context": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "type": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "id": { + "type": "string", + "readOnly": true + }, + "field0": { + "title": "Organization Name", + "description": "Organization Name", + "readOnly": false, + "$comment": "{\"term\": \"field0\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field1": { + "title": "Address line 1", + "description": "Address line 1", + "readOnly": false, + "$comment": "{\"term\": \"field1\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field2": { + "title": "Address line 2", + "description": "Address line 2", + "readOnly": false, + "$comment": "{\"term\": \"field2\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field3": { + "title": "Address line 3", + "description": "Address line 3", + "readOnly": false, + "$comment": "{\"term\": \"field3\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field4": { + "title": "Postal code", + "description": "Postal code", + "readOnly": false, + "$comment": "{\"term\": \"field4\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field5": { + "title": "Country", + "description": "Country", + "readOnly": false, + "$comment": "{\"term\": \"field5\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field6": { + "title": "Contact person", + "description": "Contact person", + "readOnly": false, + "$comment": "{\"term\": \"field6\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field7": { + "title": "e-mail", + "description": "e-mail", + "readOnly": false, + "$comment": "{\"term\": \"field7\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string", + "format": "email" + }, + "field8": { + "title": "Telephone", + "description": "Telephone", + "readOnly": false, + "$comment": "{\"term\": \"field8\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field9": { + "title": "Fax", + "description": "Fax", + "readOnly": false, + "$comment": "{\"term\": \"field9\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field10": { + "title": "Existing I-REC Registry organization(s) to become subsidiary", + "description": "Existing I-REC Registry organization(s) to become subsidiary", + "readOnly": false, + "$comment": "{\"term\": \"field10\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + } + }, + "required": [ + "@context", + "type" + ], + "additionalProperties": false + }, + "#66b7a5fe-2c17-422d-9744-b4b55c2174b9": { + "$id": "#66b7a5fe-2c17-422d-9744-b4b55c2174b9", + "$comment": "{\"term\": \"66b7a5fe-2c17-422d-9744-b4b55c2174b9\", \"@id\": \"https://ipfs.io/ipfs/bafkreicwhwmdbu4r3zv3cfifbb47dd7y5bf7l6qzycf66ll6pskk2r7gyq#66b7a5fe-2c17-422d-9744-b4b55c2174b9\"}", + "title": "Lead User Details", + "description": "Lead User Details", + "type": "object", + "properties": { + "@context": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "type": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "readOnly": true + }, + "id": { + "type": "string", + "readOnly": true + }, + "field0": { + "title": "Family Name (surname)", + "description": "Family Name (surname)", + "readOnly": false, + "$comment": "{\"term\": \"field0\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field1": { + "title": "Other (Given) Names", + "description": "Other (Given) Names", + "readOnly": false, + "$comment": "{\"term\": \"field1\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field2": { + "title": "Title", + "description": "Title", + "readOnly": false, + "$comment": "{\"term\": \"field2\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field3": { + "title": "e-mail", + "description": "e-mail", + "readOnly": false, + "$comment": "{\"term\": \"field3\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string", + "format": "email" + }, + "field4": { + "title": "Telephone", + "description": "Telephone", + "readOnly": false, + "$comment": "{\"term\": \"field4\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + }, + "field5": { + "title": "Fax", + "description": "Fax", + "readOnly": false, + "$comment": "{\"term\": \"field5\", \"@id\": \"https://www.schema.org/text\"}", + "type": "string" + } + }, + "required": [ + "@context", + "type" + ], + "additionalProperties": false + } + } + }, + "context": { + "@context": { + "@version": 1.1, + "@vocab": "https://w3id.org/traceability/#undefinedTerm", + "id": "@id", + "type": "@type", + "6d009939-3c53-44fd-8a0c-c9d98472ff09": { + "@id": "https://ipfs.io/ipfs/bafkreihe55hxacf32sxuybe3s3otblhfs3y5qlk3lccjvksh7kncwf6ura#6d009939-3c53-44fd-8a0c-c9d98472ff09", + "@context": { + "field0": { + "@id": "https://www.schema.org/text" + }, + "field1": { + "@id": "https://www.schema.org/text" + }, + "field2": { + "@id": "https://www.schema.org/text" + }, + "field3": { + "@id": "https://www.schema.org/text" + }, + "field4": { + "@id": "https://www.schema.org/text" + }, + "field5": { + "@id": "https://www.schema.org/text" + }, + "field6": { + "@id": "https://www.schema.org/text" + }, + "field7": { + "@id": "https://www.schema.org/text" + }, + "field8": { + "@id": "https://www.schema.org/text" + }, + "field9": { + "@id": "https://www.schema.org/text" + }, + "field10": { + "@id": "https://www.schema.org/text" + }, + "field11": { + "@id": "https://www.schema.org/text" + }, + "field12": { + "@id": "https://www.schema.org/text" + }, + "field13": { + "@id": "https://www.schema.org/text" + }, + "field14": { + "@id": "https://www.schema.org/text" + }, + "field15": { + "@id": "https://www.schema.org/text" + }, + "field16": { + "@id": "https://www.schema.org/text" + }, + "field17": { + "@id": "https://www.schema.org/text" + }, + "field18": { + "@id": "https://www.schema.org/text" + }, + "field19": { + "@id": "https://www.schema.org/text" + } + } + }, + "e0d61835-0491-4df8-9d48-21e961a7916f": { + "@id": "https://ipfs.io/ipfs/bafkreidwms3pistbvq472d3zkhpll7eth7azpwmftour4xmzrntvibhk2u#e0d61835-0491-4df8-9d48-21e961a7916f", + "@context": { + "field0": { + "@id": "https://www.schema.org/text" + }, + "field1": { + "@id": "https://www.schema.org/text" + }, + "field2": { + "@id": "https://www.schema.org/text" + }, + "field3": { + "@id": "https://www.schema.org/text" + }, + "field4": { + "@id": "https://www.schema.org/text" + }, + "field5": { + "@id": "https://www.schema.org/text" + }, + "field6": { + "@id": "https://www.schema.org/text" + }, + "field7": { + "@id": "https://www.schema.org/text" + }, + "field8": { + "@id": "https://www.schema.org/text" + }, + "field9": { + "@id": "https://www.schema.org/text" + }, + "field10": { + "@id": "https://www.schema.org/text" + } + } + }, + "66b7a5fe-2c17-422d-9744-b4b55c2174b9": { + "@id": "https://ipfs.io/ipfs/bafkreicwhwmdbu4r3zv3cfifbb47dd7y5bf7l6qzycf66ll6pskk2r7gyq#66b7a5fe-2c17-422d-9744-b4b55c2174b9", + "@context": { + "field0": { + "@id": "https://www.schema.org/text" + }, + "field1": { + "@id": "https://www.schema.org/text" + }, + "field2": { + "@id": "https://www.schema.org/text" + }, + "field3": { + "@id": "https://www.schema.org/text" + }, + "field4": { + "@id": "https://www.schema.org/text" + }, + "field5": { + "@id": "https://www.schema.org/text" + } + } + }, + "732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0": { + "@id": "https://ipfs.io/ipfs/bafkreiejsgxjj4ntamvgattviac5vtf5rtpvnvmojk444lyawutwsfnvwi#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "@context": { + "field0": { + "@id": "https://www.schema.org/text" + }, + "policyId": { + "@id": "https://www.schema.org/text" + }, + "ref": { + "@id": "https://www.schema.org/text" + }, + "field1": { + "@id": "https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#6d009939-3c53-44fd-8a0c-c9d98472ff09" + }, + "field2": { + "@id": "https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#e0d61835-0491-4df8-9d48-21e961a7916f" + }, + "field3": { + "@id": "https://ipfs.io/ipfs/bafkreihxsmllnneje7shxerizd4nmjj3mg4mexaskixzkskqpdsksyd6qe#66b7a5fe-2c17-422d-9744-b4b55c2174b9" + } + } + } + } + }, + "type": "732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "fields": [ + { + "name": "field0", + "title": "Date", + "description": "Date", + "type": "string", + "format": "date", + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field1", + "title": "Applicant Details", + "description": "Applicant Details", + "type": "#6d009939-3c53-44fd-8a0c-c9d98472ff09", + "format": null, + "pattern": null, + "required": true, + "isRef": true, + "isArray": false, + "readOnly": false, + "fields": [ + { + "name": "field0", + "title": "Applicant Legal Name", + "description": "Applicant Legal Name", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field1", + "title": "Registered address line 1", + "description": "Registered address line 1", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field2", + "title": "Registered address line 2", + "description": "Registered address line 2", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field3", + "title": "Registered address line 3", + "description": "Registered address line 3", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field4", + "title": "Postal (ZIP) code", + "description": "Postal (ZIP) code", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field5", + "title": "Country", + "description": "Country", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field6", + "title": "Legal Status", + "description": "Legal Status", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field7", + "title": "Country of company registration/private residence", + "description": "Country of company registration/private residence", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field8", + "title": "Corporate registration number/passport number", + "description": "Corporate registration number/passport number", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field9", + "title": "VAT number", + "description": "VAT number", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field10", + "title": "Website URL", + "description": "Website URL", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field11", + "title": "Main business (e.g. food retailer)", + "description": "Main business (e.g. food retailer)", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field12", + "title": "Year of registration", + "description": "Year of registration", + "type": "integer", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field13", + "title": "Approximate number of employees", + "description": "Approximate number of employees", + "type": "integer", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field14", + "title": "Name of the Chief Executive Officer/General Manager", + "description": "Name of the Chief Executive Officer/General Manager", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field15", + "title": "Chief Executive Officer/General Manager passport number", + "description": "Chief Executive Officer/General Manager passport number", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field16", + "title": "Please state in which countries the organization is active", + "description": "Please state in which countries the organization is active", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field17", + "title": "Please list the main (>10%) shareholders ", + "description": "Please list the main (>10%) shareholders ", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field18", + "title": "Balance sheet total for last financial year (in USD)", + "description": "Balance sheet total for last financial year (in USD)", + "type": "number", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field19", + "title": "Email address for Accounts Department", + "description": "Email address for Accounts Department", + "type": "string", + "format": "email", + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + } + ], + "context": { + "type": "6d009939-3c53-44fd-8a0c-c9d98472ff09", + "context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ] + }, + "conditions": [] + }, + { + "name": "field2", + "title": "Primary Contact Details", + "description": "Primary Contact Details", + "type": "#e0d61835-0491-4df8-9d48-21e961a7916f", + "format": null, + "pattern": null, + "required": true, + "isRef": true, + "isArray": false, + "readOnly": false, + "fields": [ + { + "name": "field0", + "title": "Organization Name", + "description": "Organization Name", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field1", + "title": "Address line 1", + "description": "Address line 1", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field2", + "title": "Address line 2", + "description": "Address line 2", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field3", + "title": "Address line 3", + "description": "Address line 3", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field4", + "title": "Postal code", + "description": "Postal code", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field5", + "title": "Country", + "description": "Country", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field6", + "title": "Contact person", + "description": "Contact person", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field7", + "title": "e-mail", + "description": "e-mail", + "type": "string", + "format": "email", + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field8", + "title": "Telephone", + "description": "Telephone", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field9", + "title": "Fax", + "description": "Fax", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field10", + "title": "Existing I-REC Registry organization(s) to become subsidiary", + "description": "Existing I-REC Registry organization(s) to become subsidiary", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + } + ], + "context": { + "type": "e0d61835-0491-4df8-9d48-21e961a7916f", + "context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ] + }, + "conditions": [] + }, + { + "name": "field3", + "title": "Lead User Details\t", + "description": "Lead User Details\t", + "type": "#66b7a5fe-2c17-422d-9744-b4b55c2174b9", + "format": null, + "pattern": null, + "required": true, + "isRef": true, + "isArray": false, + "readOnly": false, + "fields": [ + { + "name": "field0", + "title": "Family Name (surname)", + "description": "Family Name (surname)", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field1", + "title": "Other (Given) Names", + "description": "Other (Given) Names", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field2", + "title": "Title", + "description": "Title", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field3", + "title": "e-mail", + "description": "e-mail", + "type": "string", + "format": "email", + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field4", + "title": "Telephone", + "description": "Telephone", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + }, + { + "name": "field5", + "title": "Fax", + "description": "Fax", + "type": "string", + "format": null, + "pattern": null, + "required": false, + "isRef": false, + "isArray": false, + "readOnly": false, + "fields": null, + "context": null, + "conditions": null + } + ], + "context": { + "type": "66b7a5fe-2c17-422d-9744-b4b55c2174b9", + "context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ] + }, + "conditions": [] + } + ], + "conditions": [] + }, + "presetFields": [], + "uiMetaData": { + "type": "page", + "title": "Registrant Application" + }, + "hideFields": [], + "active": true, + "data": null +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Create Registrant + +{% swagger method="post" path="" baseUrl="/policies/{{policyId}}/blocks/{{create_application_uuid}}" summary="Creating Registrant" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="document" %} +{ "type": "{{registrant_schema_type}}", "@context": [ "{{registrant_schema_context}}" ], "field0": "2022-05-11", "field1": { "type": "{{registrant_schema_field1_type}}", "@context": [ "{{registrant_schema_field1_context}}" ], "field0": "Applicant Legal Name", "field1": "Registered address line 1", "field2": "Registered address line 2", "field3": "Registered address line 3", "field4": "Postal (ZIP) code", "field5": "Country", "field6": "Legal Status", "field7": "Country of company registration/private residence", "field8": "Corporate registration number/passport number", "field9": "VAT number", "field10": "Website URL", "field11": "Main business (e.g. food retailer)", "field12": 1, "field13": 1, "field14": "Name of the Chief Executive Officer/General Manager", "field15": "Chief Executive Officer/General Manager passport number", "field16": "Please state in which countries the organization is active", "field17": "Please list the main (>10%) shareholders", "field18": 1, "field19": "email@email.com" }, "field2": { "type": "{{registrant_schema_field2_type}}", "@context": [ "{{registrant_schema_field2_context}}" ], "field0": "Organization Name", "field1": "Address line 1", "field2": "Address line 2", "field3": "Address line 3", "field4": "Postal code", "field5": "Country", "field6": "Contact person", "field7": "email@email.com", "field8": "123456789", "field9": "Fax", "field10": "Existing I-REC Registry organization(s) to become subsidiary" }, "field3": { "type": "{{registrant_schema_field3_type}}", "@context": [ "{{registrant_schema_field3_context}}" ], "field0": "Family Name (surname)", "field1": "Other (Given) Names", "field2": "Title", "field3": "email@email.com", "field4": "123456789", "field5": "Fax" } +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="ref" %} +null +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Get Approved Registrant + +{% swagger method="get" path="" baseUrl="/policies/{{policyId}}/tag/approve_registrant_btn" summary="Displaying Approved Registrant uuid" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "id": "c2eef66b-ec9f-42c5-99b2-430625c49e88" +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Get Grid Documents + +{% swagger method="get" path="" baseUrl="/policies/{{policyId}}/blocks/{{registrants_grid_uuid}}" summary="Displaying Grid Documents" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="" %} +```javascript +{ + "data": [ + { + "id": "628291ed93e1d09322c4ed1a", + "owner": "did:hedera:testnet:2naXnVQ86KZySwwWfMzh6Y9Tfj6mCHj5hY8sjLQvxP3B;hedera:testnet:tid=0.0.34824275", + "hash": "Ew2Wz27nWJnN1fUTPZz1mthDkxejKuQdTbgVxKfacXRx", + "document": { + "id": "53b10c87-5ab5-445a-959c-51dc78e12270", + "type": [ + "VerifiableCredential" + ], + "issuer": "did:hedera:testnet:2naXnVQ86KZySwwWfMzh6Y9Tfj6mCHj5hY8sjLQvxP3B;hedera:testnet:tid=0.0.34824275", + "issuanceDate": "2022-05-16T18:03:17.381Z", + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "credentialSubject": [ + { + "field0": "2022-05-11", + "field1": { + "type": "6d009939-3c53-44fd-8a0c-c9d98472ff09", + "@context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ], + "field0": "Applicant Legal Name", + "field1": "Registered address line 1", + "field2": "Registered address line 2", + "field3": "Registered address line 3", + "field4": "Postal (ZIP) code", + "field5": "Country", + "field6": "Legal Status", + "field7": "Country of company registration/private residence", + "field8": "Corporate registration number/passport number", + "field9": "VAT number", + "field10": "Website URL", + "field11": "Main business (e.g. food retailer)", + "field12": 1, + "field13": 1, + "field14": "Name of the Chief Executive Officer/General Manager", + "field15": "Chief Executive Officer/General Manager passport number", + "field16": "Please state in which countries the organization is active", + "field17": "Please list the main (>10%) shareholders", + "field18": 1, + "field19": "email@email.com" + }, + "field2": { + "type": "e0d61835-0491-4df8-9d48-21e961a7916f", + "@context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ], + "field0": "Organization Name", + "field1": "Address line 1", + "field2": "Address line 2", + "field3": "Address line 3", + "field4": "Postal code", + "field5": "Country", + "field6": "Contact person", + "field7": "email@email.com", + "field8": "123456789", + "field9": "Fax", + "field10": "Existing I-REC Registry organization(s) to become subsidiary" + }, + "field3": { + "type": "66b7a5fe-2c17-422d-9744-b4b55c2174b9", + "@context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ], + "field0": "Family Name (surname)", + "field1": "Other (Given) Names", + "field2": "Title", + "field3": "email@email.com", + "field4": "123456789", + "field5": "Fax" + }, + "policyId": "6282755493e1d09322c4ed13", + "@context": [ + "https://ipfs.io/ipfs/bafkreib7o25julfdxlg2ls4acie4rvdohaxhq22kbjfys4ssykr7ng3m2i" + ], + "id": "did:hedera:testnet:2naXnVQ86KZySwwWfMzh6Y9Tfj6mCHj5hY8sjLQvxP3B;hedera:testnet:tid=0.0.34824275", + "type": "732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0" + } + ], + "proof": { + "type": "Ed25519Signature2018", + "created": "2022-05-16T18:03:17Z", + "verificationMethod": "did:hedera:testnet:2naXnVQ86KZySwwWfMzh6Y9Tfj6mCHj5hY8sjLQvxP3B;hedera:testnet:tid=0.0.34824275#did-root-key", + "proofPurpose": "assertionMethod", + "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2JLSx0OPaqvGUkbnIt0vVtJMO9H8h5K-Jvkl6pobJ3rGXauflV2_TV3jlDccC7z1K_euLMz2iOJfrAQld5y3DQ" + } + }, + "createDate": "2022-05-16T18:03:25.894Z", + "updateDate": "2022-05-16T18:03:25.894Z", + "hederaStatus": "ISSUE", + "signature": 0, + "type": "registrant", + "policyId": "6282755493e1d09322c4ed13", + "tag": "create_application(db)", + "option": { + "status": "Waiting for approval" + }, + "schema": "#732d99d8-b254-4aa7-8bb4-e78f15212892&1.0.0", + "messageId": "1652724204.003778404", + "topicId": "0.0.34825558", + "relationships": [], + "__sourceTag__": "registrants_source(need_approve)" + } + ], + "blocks": [], + "commonAddons": [ + { + "id": "bb1b84e4-3524-4849-a646-cca3623b0d75", + "blockType": "documentsSourceAddon" + }, + { + "id": "1adf6b92-a184-43f4-99ab-3113fee26fa1", + "blockType": "documentsSourceAddon" + } + ], + "fields": [ + { + "title": "Legal Name", + "name": "document.credentialSubject.0.field1.field0", + "type": "text" + }, + { + "title": "Organization Name", + "name": "document.credentialSubject.0.field2.field0", + "type": "text" + }, + { + "title": "Operation", + "name": "option.status", + "type": "text", + "width": "250px", + "bindGroup": "registrants_source(approved)", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "" + }, + { + "title": "Operation", + "name": "option.status", + "tooltip": "", + "type": "block", + "action": "", + "url": "", + "dialogContent": "", + "dialogClass": "", + "dialogType": "", + "bindBlock": "approve_registrant_btn", + "width": "250px", + "bindGroup": "registrants_source(need_approve)" + }, + { + "name": "document", + "title": "Document", + "tooltip": "", + "type": "button", + "action": "dialog", + "content": "View Document", + "uiClass": "link", + "dialogContent": "VC", + "dialogClass": "", + "dialogType": "json" + } + ] +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Approve Registrant + +{% swagger method="post" path="" baseUrl="/policies/{{policyId}}/blocks/{{approve_registrant_btn_uuid}}" summary="Approving Registrant" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-parameter in="body" name="reg" %} + +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} +{% endswagger %} + +#### Getting uuid of device created + +{% swagger method="get" path="" baseUrl="/policies/{{policyId}}/tag/create_device_form" summary="Getting uuid of created device" %} +{% swagger-description %} + +{% endswagger-description %} + +{% swagger-response status="200: OK" description="" %} +```javascript +{ + "id": "bb8ddf01-e056-4632-8aa1-7c1c8aa5a1ee" +} +``` +{% endswagger-response %} +{% endswagger %} + +#### + +### Setting up the User Role + +BLOCK : choose\_role + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="User Role" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/88ea01cb-35ae-4e4d-87ce-ec93d577cd30 +{% endswagger-description %} + +{% swagger-parameter in="body" name="role" type="String" required="true" %} +Registrant +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Submitting Registrant Application Form + +BLOCK : create\_application + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Registrant Application form to be submitted" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/8ae8f020-42ed-4692-9d93-4d700d467bd0 +{% endswagger-description %} + +{% swagger-parameter in="body" name="document" %} + "field0":"2022-04-01", + + "field1":{ + + "field0":"Applicant Legal Name", + + "field1":"Registered address line 1", + + "field2":"Registered address line 2", + + "field3":"Registered address line 3", + + "field4":"Postal (ZIP) code", + + "field5":"Country", + + "field6":"Legal Status", + + "field7":"Country of company registration/private residence", + + "field8":"Corporate registration number/passport number", + + "field9":"VAT number", + + "field10":"Website URL", + + "field11":"Main business (e.g. food retailer)", + + "field12":2022, + + "field13":1, + + "field14":"Name of the Chief Executive Officer/General Manager", + + "field15":"Chief Executive Officer/General Manager passport number", + + "field16":"Please state in which countries the organization is active", + + "field17":"Please list the main (>10%) shareholders", + + "field18":1, + + "field19":"test@mail.ru", + + "type":"4510d95d-ed9d-4785-a5ed-5c1e334611dd", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field2":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field3":{ + + "field0":"Family Name (surname)", + + "field1":"Other (Given) Names", + + "field2":"Title", + + "field3":"test@mail.ru", + + "field4":"Telephone", + + "field5":"Fax", + + "type":"fb8c1458-e86f-444a-a408-665149bda777", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "type":"762694d6-8fbb-4377-ae3e-ef400bbc3ea5&1.0.0", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="ref" %} +null +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Get Registrant Application to Approve) + +#### Make GET request and get data\[i] and change option.status = “Approved” + +BLOCK : registrants\_grid + +{% swagger method="get" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Getting Registrant Application for approval" %} +{% swagger-description %} +/policies/626c0490d24497fe1b1e415d/blocks/2f237418-9ed5-4a1e-a2ea-c7f978554784 +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "data":[ + { + "id":"626c056cd24497fe1b1e4163", + "owner":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "hash":"GkX1mNd5wxWKCdkBYC6PBGHm9jmkNzsjb9ycqcP4jgPb", + "document":{ + "id":"9d537f1d-c906-4013-9ac6-c6a0fd211e4a", + "type":[ + "VerifiableCredential" + ], + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "issuanceDate":"2022-04-29T15:33:48.168Z", + "@context":[ + "https://www.w3.org/2018/credentials/v1" + ], + "credentialSubject":[ + { + "field0":"2022-04-08", + "field1":{ + "field0":"Applicant Legal Name", + "field1":"Registered address line 1", + "field2":"Registered address line 2", + "field3":"Registered address line 3", + "field4":"Postal (ZIP) code", + "field5":"Country", + "field6":"Legal Status", + "field7":"Country of company registration/private residence", + "field8":"Corporate registration number/passport number", + "field9":"VAT number", + "field10":"Website URL", + "field11":"Main business (e.g. food retailer)", + "field12":1, + "field13":1, + "field14":"Name of the Chief Executive Officer/General Manager", + "field15":"Chief Executive Officer/General Manager passport number", + "field16":"Please state in which countries the organization is active", + "field17":"Please list the main (>10%) shareholders", + "field18":1, + "field19":"test@mail.ru", + "type":"f7bd122d-4220-4d9d-abb2-fa9366e79975", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "field2":{ + "field0":"Organization Name", + "field1":"Address line 1", + "field2":"Address line 2", + "field3":"Address line 3", + "field4":"Postal code", + "field5":"Country", + "field6":"Contact person", + "field7":"test@mail.ru", + "field8":"Telephone", + "field9":"Fax", + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + "type":"a68073e6-bf56-43e3-99c4-5b433c983654", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "field3":{ + "field0":"Family Name (surname)", + "field1":"Other (Given) Names", + "field2":"Title", + "field3":"test@mail.ru", + "field4":"Telephone", + "field5":"Fax", + "type":"9dca2898-d548-48a4-beec-fefd308f93cf", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "policyId":"626c0490d24497fe1b1e415d", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ], + "id":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "type":"7b652d73-5978-45b4-992e-cc3ce732e27a&1.0.0" + } + ], + "proof":{ + "type":"Ed25519Signature2018", + "created":"2022-04-29T15:33:48Z", + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + "proofPurpose":"assertionMethod", + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GaOyMZ9dR5J0-iu6SICVNlWifON3DT0ytz2z_eCHeOSRY5oQ7Jb3219G7aUrztIEppMcfzG6teO-YvuNPiAfBw" + } + }, + "createDate":"2022-04-29T15:34:04.021Z", + "updateDate":"2022-04-29T15:34:04.021Z", + "hederaStatus":"ISSUE", + "signature":0, + "type":"registrant", + "policyId":"626c0490d24497fe1b1e415d", + "tag":"create_application(db)", + "option":{ + "status":"Waiting for approval" + }, + "schema":"#7b652d73-5978-45b4-992e-cc3ce732e27a&1.0.0", + "messageId":"1651246443.516813000", + "topicId":"0.0.34352381", + "relationships":[ + + ], + "__sourceTag__":"registrants_source(need_approve)" + } + ], + "blocks":[ + + ], + "commonAddons":[ + { + "id":"c0dbe6b1-6963-4010-9dc4-c676679376dd", + "blockType":"documentsSourceAddon" + }, + { + "id":"540a115b-a94e-4d16-af46-e4b817f07b98", + "blockType":"documentsSourceAddon" + } + ], + "fields":[ + { + "title":"Legal Name", + "name":"document.credentialSubject.0.field1.field0", + "type":"text" + }, + { + "title":"Organization Name", + "name":"document.credentialSubject.0.field2.field0", + "type":"text" + }, + { + "title":"Operation", + "name":"option.status", + "type":"text", + "width":"250px", + "bindGroup":"registrants_source(approved)", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"" + }, + { + "title":"Operation", + "name":"option.status", + "tooltip":"", + "type":"block", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"approve_registrant_btn", + "width":"250px", + "bindGroup":"registrants_source(need_approve)" + }, + { + "name":"document", + "title":"Document", + "tooltip":"", + "type":"button", + "action":"dialog", + "content":"View Document", + "uiClass":"link", + "dialogContent":"VC", + "dialogClass":"", + "dialogType":"json" + } + ] +} + +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Approve Registrant Application) + +BLOCK : approve\_registrant\_btn + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Approving Registrant Application" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/7f091726-126e-4bc7-8e2e-9cd7bb220ed0 +{% endswagger-description %} + +{% swagger-parameter in="body" name="id" %} +626bf6ddd24497fe1b1e413f +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="owner" %} +did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hash" %} +25J2gLm7phAEFu5yyQtVa8WqjUd8pDaxX1n6CtKR91rQ +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="document" %} + "id":"ebdc5776-e756-4cda-8e10-04c04adc535b", + + "type":\[ + + "VerifiableCredential" + + ], + + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "issuanceDate":"2022-04-29T14:31:39.500Z", + + "@context":\[ + + "https://www.w3.org/2018/credentials/v1" + + ], + + "credentialSubject":\[ + + { + + "field0":"2022-04-01", + + "field1":{ + + "field0":"Applicant Legal Name", + + "field1":"Registered address line 1", + + "field2":"Registered address line 2", + + "field3":"Registered address line 3", + + "field4":"Postal (ZIP) code", + + "field5":"Country", + + "field6":"Legal Status", + + "field7":"Country of company registration/private residence", + + "field8":"Corporate registration number/passport number", + + "field9":"VAT number", + + "field10":"Website URL", + + "field11":"Main business (e.g. food retailer)", + + "field12":2022, + + "field13":1, + + "field14":"Name of the Chief Executive Officer/General Manager", + + "field15":"Chief Executive Officer/General Manager passport number", + + "field16":"Please state in which countries the organization is active", + + "field17":"Please list the main (>10%) shareholders", + + "field18":1, + + "field19":"test@mail.ru", + + "type":"4510d95d-ed9d-4785-a5ed-5c1e334611dd", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field2":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field3":{ + + "field0":"Family Name (surname)", + + "field1":"Other (Given) Names", + + "field2":"Title", + + "field3":"test@mail.ru", + + "field4":"Telephone", + + "field5":"Fax", + + "type":"fb8c1458-e86f-444a-a408-665149bda777", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "policyId":"626bf178d24497fe1b1e4139", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ], + + "id":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "type":"762694d6-8fbb-4377-ae3e-ef400bbc3ea5&1.0.0" + + } + + ], + + "proof":{ + + "type":"Ed25519Signature2018", + + "created":"2022-04-29T14:31:39Z", + + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + + "proofPurpose":"assertionMethod", + + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..I1EzRS7Ct-CaDMaNYuMKi\_GseppZm9jtIJMZbilchmWlV7W3mNsapSSche8UzAWYfKnhwjQuwvlMr0c8HlVEBQ" + + } +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="createDate" %} +2022-04-29T14:31:57.918Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="updateDate" %} +2022-04-29T14:31:57.918Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hederaStatus" %} +ISSUE +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="signature" %} +0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="type" %} +registrant +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="policyID" %} +626bf178d24497fe1b1e4139 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="tag" %} +create_application(db) +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="option" %} +{ + + "status":"Approved" + + }, +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="schema" %} +\#762694d6-8fbb-4377-ae3e-ef400bbc3ea5&1.0.0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="messageId" %} +1651242715.948867898 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="topidId" %} +0.0.34350746 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="relationships" %} +null +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="__sourceTag__" %} +registrants_source(need_approve) +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### User (CREATE DEVICE) + +BLOCK : create\_device\_form + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Creating Device" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/3db29027-8753-4e7f-af40-ca31b72ce95c +{% endswagger-description %} + +{% swagger-parameter in="body" name="document" %} +"field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "field1":"2022-04-08", + + "field2":"Is the Registrant also the owner of the Device? (provide evidence)", + + "field3":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field4":{ + + "field0":"Device Name", + + "field1":"Address", + + "field2":"Postal code", + + "field3":"Country", + + "field4":"Longitude", + + "field5":"Latitude", + + "field6":"TSO’s ID for measurement point", + + "field7":1, + + "field8":1, + + "field9":"2022-04-29", + + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + + "field12":"Expected form of volume evidence", + + "field13":"If other please specify", + + "type":"fd49e6e4-58d7-425a-9518-9a2c4a178b15", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field5":{ + + "field0":"Energy Source (Input) – see Appendix 2", + + "field1":"Technology – see Appendix 2", + + "field2":true, + + "field3":"If yes give details", + + "field4":true, + + "field5":"If yes give details", + + "field6":"Please give details of how the site can import electricity by means other than through the meter(s) specified above", + + "field7":"Please give details (including registration id) of any carbon offset or energy tracking scheme for which the Production Device is registered. State ‘None’ if that is the case", + + "field8":"Please identify any labeling schemes for which the Device is accredited", + + "field9":true, + + "field10":"If public (government) funding has been received when did/will it finish?", + + "field11":"2022-04-29", + + "field12":"Preferred I-REC Device Verifier", + + "type":"d7a15512-bb46-4826-864d-1e37bf7b321f", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "type":"4713cc2e-4036-49b6-ba19-6475ed590c33&1.0.0", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="ref" %} + "id":"626bf76ad24497fe1b1e4140", + + "owner":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "hash":"BQTRbH4qtRfAXWW8T7EAa5vEncnNEEnaj8CT2ax7YJBs", + + "document":{ + + "id":"849228e1-4c7d-4bf4-8eb4-df1f3c24429b", + + "type":\[ + + "VerifiableCredential" + + ], + + "issuer":"did:hedera:testnet:A7cP5xLNaF5LPtXkDUTsP6fATh4uarAjCujnZ3qR2vcw;hedera:testnet:tid=0.0.34349531", + + "issuanceDate":"2022-04-29T14:34:10.327Z", + + "@context":\[ + + "https://www.w3.org/2018/credentials/v1" + + ], + + "credentialSubject":\[ + + { + + "field0":"2022-04-01", + + "field1":{ + + "field0":"Applicant Legal Name", + + "field1":"Registered address line 1", + + "field2":"Registered address line 2", + + "field3":"Registered address line 3", + + "field4":"Postal (ZIP) code", + + "field5":"Country", + + "field6":"Legal Status", + + "field7":"Country of company registration/private residence", + + "field8":"Corporate registration number/passport number", + + "field9":"VAT number", + + "field10":"Website URL", + + "field11":"Main business (e.g. food retailer)", + + "field12":2022, + + "field13":1, + + "field14":"Name of the Chief Executive Officer/General Manager", + + "field15":"Chief Executive Officer/General Manager passport number", + + "field16":"Please state in which countries the organization is active", + + "field17":"Please list the main (>10%) shareholders", + + "field18":1, + + "field19":"test@mail.ru", + + "type":"4510d95d-ed9d-4785-a5ed-5c1e334611dd", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field2":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "field3":{ + + "field0":"Family Name (surname)", + + "field1":"Other (Given) Names", + + "field2":"Title", + + "field3":"test@mail.ru", + + "field4":"Telephone", + + "field5":"Fax", + + "type":"fb8c1458-e86f-444a-a408-665149bda777", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ] + + }, + + "policyId":"626bf178d24497fe1b1e4139", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreighh26v7eg7xsfzie674yhgz4ph3wf5yjadbec4wynyfevoshtdty" + + ], + + "id":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "type":"762694d6-8fbb-4377-ae3e-ef400bbc3ea5&1.0.0" + + } + + ], + + "proof":{ + + "type":"Ed25519Signature2018", + + "created":"2022-04-29T14:34:10Z", + + "verificationMethod":"did:hedera:testnet:A7cP5xLNaF5LPtXkDUTsP6fATh4uarAjCujnZ3qR2vcw;hedera:testnet:tid=0.0.34349531#did-root-key", + + "proofPurpose":"assertionMethod", + + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..rjry6W0iAoXzRx7Upb6hxeu0LbxjuNwDULq2p4IIQsOFwY5h4zxBCOVZIGmwIJ\_xY2a0V0-pyX1xTwTUV8aPDQ" + + } + + }, + + "createDate":"2022-04-29T14:34:18.048Z", + + "updateDate":"2022-04-29T14:34:18.048Z", + + "hederaStatus":"ISSUE", + + "signature":0, + + "type":"registrant(Approved)", + + "policyId":"626bf178d24497fe1b1e4139", + + "tag":"save\_copy\_application", + + "option":{ + + "status":"Approved" + + }, + + "schema":"#762694d6-8fbb-4377-ae3e-ef400bbc3ea5&1.0.0", + + "messageId":"1651242856.179215415", + + "topicId":"0.0.34350746", + + "relationships":\[ + + "1651242715.948867898" + + ], + + "\_\_sourceTag\_\_":"current\_registrant" + + } +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Get Device to Approve) + +#### Make GET request and get data\[i] and change option.status = “Approved”: + +BLOCK : approve\_devices\_grid + +{% swagger method="get" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Submitting Device for Approval" %} +{% swagger-description %} +/policies/626c0490d24497fe1b1e415d/blocks/2d99bfd9-38d3-4777-abda-f1ea5cecb613 +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "data":[ + { + "id":"626c056cd24497fe1b1e4163", + "owner":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "hash":"GkX1mNd5wxWKCdkBYC6PBGHm9jmkNzsjb9ycqcP4jgPb", + "document":{ + "id":"9d537f1d-c906-4013-9ac6-c6a0fd211e4a", + "type":[ + "VerifiableCredential" + ], + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "issuanceDate":"2022-04-29T15:33:48.168Z", + "@context":[ + "https://www.w3.org/2018/credentials/v1" + ], + "credentialSubject":[ + { + "field0":"2022-04-08", + "field1":{ + "field0":"Applicant Legal Name", + "field1":"Registered address line 1", + "field2":"Registered address line 2", + "field3":"Registered address line 3", + "field4":"Postal (ZIP) code", + "field5":"Country", + "field6":"Legal Status", + "field7":"Country of company registration/private residence", + "field8":"Corporate registration number/passport number", + "field9":"VAT number", + "field10":"Website URL", + "field11":"Main business (e.g. food retailer)", + "field12":1, + "field13":1, + "field14":"Name of the Chief Executive Officer/General Manager", + "field15":"Chief Executive Officer/General Manager passport number", + "field16":"Please state in which countries the organization is active", + "field17":"Please list the main (>10%) shareholders", + "field18":1, + "field19":"test@mail.ru", + "type":"f7bd122d-4220-4d9d-abb2-fa9366e79975", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "field2":{ + "field0":"Organization Name", + "field1":"Address line 1", + "field2":"Address line 2", + "field3":"Address line 3", + "field4":"Postal code", + "field5":"Country", + "field6":"Contact person", + "field7":"test@mail.ru", + "field8":"Telephone", + "field9":"Fax", + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + "type":"a68073e6-bf56-43e3-99c4-5b433c983654", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "field3":{ + "field0":"Family Name (surname)", + "field1":"Other (Given) Names", + "field2":"Title", + "field3":"test@mail.ru", + "field4":"Telephone", + "field5":"Fax", + "type":"9dca2898-d548-48a4-beec-fefd308f93cf", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ] + }, + "policyId":"626c0490d24497fe1b1e415d", + "@context":[ + "https://ipfs.io/ipfs/bafkreiess6ak6lwlhar55ezckdwo6y7ki3wlyzyl3a7tadda2zuqaxwmbm" + ], + "id":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "type":"7b652d73-5978-45b4-992e-cc3ce732e27a&1.0.0" + } + ], + "proof":{ + "type":"Ed25519Signature2018", + "created":"2022-04-29T15:33:48Z", + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + "proofPurpose":"assertionMethod", + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..GaOyMZ9dR5J0-iu6SICVNlWifON3DT0ytz2z_eCHeOSRY5oQ7Jb3219G7aUrztIEppMcfzG6teO-YvuNPiAfBw" + } + }, + "createDate":"2022-04-29T15:34:04.021Z", + "updateDate":"2022-04-29T15:34:04.021Z", + "hederaStatus":"ISSUE", + "signature":0, + "type":"registrant", + "policyId":"626c0490d24497fe1b1e415d", + "tag":"create_application(db)", + "option":{ + "status":"Waiting for approval" + }, + "schema":"#7b652d73-5978-45b4-992e-cc3ce732e27a&1.0.0", + "messageId":"1651246443.516813000", + "topicId":"0.0.34352381", + "relationships":[ + + ], + "__sourceTag__":"registrants_source(need_approve)" + } + ], + "blocks":[ + + ], + "commonAddons":[ + { + "id":"c0dbe6b1-6963-4010-9dc4-c676679376dd", + "blockType":"documentsSourceAddon" + }, + { + "id":"540a115b-a94e-4d16-af46-e4b817f07b98", + "blockType":"documentsSourceAddon" + } + ], + "fields":[ + { + "title":"Legal Name", + "name":"document.credentialSubject.0.field1.field0", + "type":"text" + }, + { + "title":"Organization Name", + "name":"document.credentialSubject.0.field2.field0", + "type":"text" + }, + { + "title":"Operation", + "name":"option.status", + "type":"text", + "width":"250px", + "bindGroup":"registrants_source(approved)", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"" + }, + { + "title":"Operation", + "name":"option.status", + "tooltip":"", + "type":"block", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"approve_registrant_btn", + "width":"250px", + "bindGroup":"registrants_source(need_approve)" + }, + { + "name":"document", + "title":"Document", + "tooltip":"", + "type":"button", + "action":"dialog", + "content":"View Document", + "uiClass":"link", + "dialogContent":"VC", + "dialogClass":"", + "dialogType":"json" + } + ] +} + +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Approve Device) + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Device Approval" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/918a113d-a88b-4595-806e-823e4fbb8bf6 +{% endswagger-description %} + +{% swagger-parameter in="body" name="id" %} +626bf826d24497fe1b1e4144 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="owner" %} +did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hash" %} +2qUPLPToSW3S33DAyY2wyJe5YPpWNuZKLLhTZRBowCAn +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="document" %} +"id":"c48ffb77-58d9-4809-aaa9-ff80950142ea", + + "type":\[ + + "VerifiableCredential" + + ], + + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "issuanceDate":"2022-04-29T14:37:18.619Z", + + "@context":\[ + + "https://www.w3.org/2018/credentials/v1" + + ], + + "credentialSubject":\[ + + { + + "field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "field1":"2022-04-08", + + "field2":"Is the Registrant also the owner of the Device? (provide evidence)", + + "field3":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field4":{ + + "field0":"Device Name", + + "field1":"Address", + + "field2":"Postal code", + + "field3":"Country", + + "field4":"Longitude", + + "field5":"Latitude", + + "field6":"TSO’s ID for measurement point", + + "field7":1, + + "field8":1, + + "field9":"2022-04-29", + + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + + "field12":"Expected form of volume evidence", + + "field13":"If other please specify", + + "type":"fd49e6e4-58d7-425a-9518-9a2c4a178b15", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field5":{ + + "field0":"Energy Source (Input) – see Appendix 2", + + "field1":"Technology – see Appendix 2", + + "field2":true, + + "field3":"If yes give details", + + "field4":true, + + "field5":"If yes give details", + + "field6":"Please give details of how the site can import electricity by means other than through the meter(s) specified above", + + "field7":"Please give details (including registration id) of any carbon offset or energy tracking scheme for which the Production Device is registered. State ‘None’ if that is the case", + + "field8":"Please identify any labeling schemes for which the Device is accredited", + + "field9":true, + + "field10":"If public (government) funding has been received when did/will it finish?", + + "field11":"2022-04-29", + + "field12":"Preferred I-REC Device Verifier", + + "type":"d7a15512-bb46-4826-864d-1e37bf7b321f", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "ref":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "policyId":"626bf178d24497fe1b1e4139", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ], + + "id":"did:hedera:testnet:2PNs5TABEKMm7WNMSLrFQDSaBqkhppjPqcj9ovkbzkrq;hedera:testnet:tid=0.0.34350724", + + "type":"4713cc2e-4036-49b6-ba19-6475ed590c33&1.0.0" + + } + + ], + + "proof":{ + + "type":"Ed25519Signature2018", + + "created":"2022-04-29T14:37:18Z", + + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + + "proofPurpose":"assertionMethod", + + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..fH8UEbWTElaBYZ-mznxFndkZU29h45Px1BL8lwzL73PUpmDeDEc2iJINx6Kmh\_uxcMpm7lhkf9JKQxADEl5-Dg" + + } +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="createDate" %} +2022-04-29T14:37:26.605Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="updateDate" %} +2022-04-29T14:37:26.605Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hederaStatus" %} +ISSUE +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="signature" %} +0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="type" %} +device +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="policyId" %} +626bf178d24497fe1b1e4139 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="tag" %} +create_device +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="option" %} +{ + + "status":"Approved" + + }, +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="schema" %} +\#4713cc2e-4036-49b6-ba19-6475ed590c33&1.0.0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="messageId" %} +1651243044.613728925 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="topicId" %} +0.0.34350746 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="relationships" %} +\[ + + "1651242856.179215415 + +] +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="__sourceTag__" %} +approve_devices_source(need_approve) +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### User (CREATE ISSUE) + +BLOCK : create\_issue\_request\_form + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Creating Issue" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/8bd8c3da-043a-4ef0-8bb4-10f60bd80832 +{% endswagger-description %} + +{% swagger-parameter in="body" name="document" %} + "field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "field1":"did:hedera:testnet:2PNs5TABEKMm7WNMSLrFQDSaBqkhppjPqcj9ovkbzkrq;hedera:testnet:tid=0.0.34350724", + + "field2":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ] + + }, + + "field3":{ + + "field0":"Device Name", + + "field1":"Address", + + "field2":"Postal code", + + "field3":"Country", + + "field4":"Longitude", + + "field5":"Latitude", + + "field6":"TSO’s ID for measurement point", + + "field7":1, + + "field8":1, + + "field9":"2022-04-29", + + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + + "field12":"Expected form of volume evidence", + + "field13":"If other please specify", + + "type":"fd49e6e4-58d7-425a-9518-9a2c4a178b15", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ] + + }, + + "field4":" labeling scheme(s)", + + "field5":"2022-04-29", + + "field6":"2022-04-29", + + "field7":1, + + "field8":"2022-04-29", + + "field9":1, + + "field10":"Type a: Settlement Metering data", + + "field11":"Type b: Non-settlement Metering data", + + "field12":"Type c: Measured Volume Transfer documentation", + + "field13":"Type d: Other", + + "field14":true, + + "field15":true, + + "field16":true, + + "field17":"Installer", + + "field18":"0.0.34235315", + + "type":"88f6b2ad-5945-4086-b15c-8181654948c8&1.0.0", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ] +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="ref" %} + "id":"626bf95ed24497fe1b1e4145", + + "owner":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "hash":"Gq2osAVHzB6LpFEDXKQkeVbpcteV7pBDdFhL93SmyPt7", + + "document":{ + + "id":"aebb99c3-a897-4d71-8819-2362a43944ea", + + "type":\[ + + "VerifiableCredential" + + ], + + "issuer":"did:hedera:testnet:A7cP5xLNaF5LPtXkDUTsP6fATh4uarAjCujnZ3qR2vcw;hedera:testnet:tid=0.0.34349531", + + "iszw2suanceDate":"2022-04-29T14:42:27.523Z", + + "@context":\[ + + "https://www.w3.org/2018/credentials/v1" + + ], + + "credentialSubject":\[ + + { + + "field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "field1":"2022-04-08", + + "field2":"Is the Registrant also the owner of the Device? (provide evidence)", + + "field3":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field4":{ + + "field0":"Device Name", + + "field1":"Address", + + "field2":"Postal code", + + "field3":"Country", + + "field4":"Longitude", + + "field5":"Latitude", + + "field6":"TSO’s ID for measurement point", + + "field7":1, + + "field8":1, + + "field9":"2022-04-29", + + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + + "field12":"Expected form of volume evidence", + + "field13":"If other please specify", + + "type":"fd49e6e4-58d7-425a-9518-9a2c4a178b15", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "field5":{ + + "field0":"Energy Source (Input) – see Appendix 2", + + "field1":"Technology – see Appendix 2", + + "field2":true, + + "field3":"If yes give details", + + "field4":true, + + "field5":"If yes give details", + + "field6":"Please give details of how the site can import electricity by means other than through the meter(s) specified above", + + "field7":"Please give details (including registration id) of any carbon offset or energy tracking scheme for which the Production Device is registered. State ‘None’ if that is the case", + + "field8":"Please identify any labeling schemes for which the Device is accredited", + + "field9":true, + + "field10":"If public (government) funding has been received when did/will it finish?", + + "field11":"2022-04-29", + + "field12":"Preferred I-REC Device Verifier", + + "type":"d7a15512-bb46-4826-864d-1e37bf7b321f", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ] + + }, + + "ref":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "policyId":"626bf178d24497fe1b1e4139", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreicra2ajpwjpukzhch3ienkqcyzi7fnnjwp65nom6vq25lwra6gx4i" + + ], + + "id":"did:hedera:testnet:2PNs5TABEKMm7WNMSLrFQDSaBqkhppjPqcj9ovkbzkrq;hedera:testnet:tid=0.0.34350724", + + "type":"4713cc2e-4036-49b6-ba19-6475ed590c33&1.0.0" + + } + + ], + + "proof":{ + + "type":"Ed25519Signature2018", + + "created":"2022-04-29T14:42:27Z", + + "verificationMethod":"did:hedera:testnet:A7cP5xLNaF5LPtXkDUTsP6fATh4uarAjCujnZ3qR2vcw;hedera:testnet:tid=0.0.34349531#did-root-key", + + "proofPurpose":"assertionMethod", + + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..\_o526p84cDF4qa1z5obliK-9WGVxsadhtCIIlq8fnjTiiOlYk54lrBZ4EeOw5xJ7DTMJ2ukLEp3PvTKVqIL3CQ" + + } + + }, + + "createDate":"2022-04-29T14:42:38.469Z", + + "updateDate":"2022-04-29T14:42:38.469Z", + + "hederaStatus":"ISSUE", + + "signature":0, + + "type":"device(Approved)", + + "policyId":"626bf178d24497fe1b1e4139", + + "tag":"save\_copy\_device", + + "option":{ + + "status":"Approved" + + }, + + "schema":"#4713cc2e-4036-49b6-ba19-6475ed590c33&1.0.0", + + "messageId":"1651243356.729744000", + + "topicId":"0.0.34350746", + + "relationships":\[ + + "1651243044.613728925" + + ], + + "\_\_sourceTag\_\_":"devices\_source(approved)" + + } +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (GET ISSUE TO APPROVE) + +#### Make GET request and get data\[i] and change option.status = “Approved”: + +BLOCK issue\_requests\_grid(evident) + +{% swagger method="get" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="" %} +{% swagger-description %} +/policies/626c0490d24497fe1b1e415d/blocks/4838bdc7-f141-4c64-a5e0-a40c2b268766 +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + "data":[ + { + "id":"626c0a7cd24497fe1b1e416c", + "owner":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "hash":"44XX8ok6Y9gy6FRaTzQzaewDGPLqArqvAaWKQBrXKNqi", + "document":{ + "id":"2d20d104-35ad-49f5-8530-7444e3228c13", + "type":[ + "VerifiableCredential" + ], + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "issuanceDate":"2022-04-29T15:55:31.487Z", + "@context":[ + "https://www.w3.org/2018/credentials/v1" + ], + "credentialSubject":[ + { + "field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + "field1":"did:hedera:testnet:HyjFdpTRX2mBpiHuHHWb45hMsGejYCS6Njecy2YBXEfu;hedera:testnet:tid=0.0.34352260", + "field2":{ + "field0":"Organization Name", + "field1":"Address line 1", + "field2":"Address line 2", + "field3":"Address line 3", + "field4":"Postal code", + "field5":"Country", + "field6":"Contact person", + "field7":"test@mail.ru", + "field8":"Telephone", + "field9":"Fax", + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + "type":"a68073e6-bf56-43e3-99c4-5b433c983654", + "@context":[ + "https://ipfs.io/ipfs/bafkreidnvwylajvvgaza7fxg57fjf5dvdbgvylfkw3tsxjlbiffincxsdq" + ] + }, + "field3":{ + "field0":"Device Name", + "field1":"Address", + "field2":"Postal code", + "field3":"Country", + "field4":"Longitude", + "field5":"Latitude", + "field6":"TSO’s ID for measurement point", + "field7":1, + "field8":1, + "field9":"2022-04-29", + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + "field12":"Expected form of volume evidence", + "field13":"If other please specify", + "type":"a35f095b-ebc6-4006-a551-1f1d22c329b8", + "@context":[ + "https://ipfs.io/ipfs/bafkreidnvwylajvvgaza7fxg57fjf5dvdbgvylfkw3tsxjlbiffincxsdq" + ] + }, + "field4":"labeling scheme(s)", + "field5":"2022-04-29", + "field6":"2022-04-29", + "field7":1, + "field8":"2022-04-29", + "field9":1, + "field10":"Type a: Settlement Metering data", + "field11":"Type b: Non-settlement Metering data", + "field12":"Type c: Measured Volume Transfer documentation", + "field13":"Type d: Other", + "field14":true, + "field15":true, + "field16":true, + "field17":"Installer", + "field18":"0.0.34235315", + "ref":"did:hedera:testnet:HyjFdpTRX2mBpiHuHHWb45hMsGejYCS6Njecy2YBXEfu;hedera:testnet:tid=0.0.34352260", + "policyId":"626c0490d24497fe1b1e415d", + "@context":[ + "https://ipfs.io/ipfs/bafkreidnvwylajvvgaza7fxg57fjf5dvdbgvylfkw3tsxjlbiffincxsdq" + ], + "id":"3d31e722-7a17-4f13-a66d-c21c0042b6d3", + "type":"c8a8aae3-2125-4872-9396-ac6b4dba8c2f&1.0.0" + } + ], + "proof":{ + "type":"Ed25519Signature2018", + "created":"2022-04-29T15:55:31Z", + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + "proofPurpose":"assertionMethod", + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..2MmXAW9khzXExyU2NVfBWTAQxro_eLWO6zxyABGb2nWvdsg5RcjmV-e_8HggxclU9wVECDW337gVFv_hkT0ZBA" + } + }, + "createDate":"2022-04-29T15:55:40.477Z", + "updateDate":"2022-04-29T15:55:40.477Z", + "hederaStatus":"ISSUE", + "signature":0, + "type":"issue_request", + "policyId":"626c0490d24497fe1b1e415d", + "tag":"create_issue_request", + "option":{ + "status":"Waiting for approval" + }, + "schema":"#c8a8aae3-2125-4872-9396-ac6b4dba8c2f&1.0.0", + "messageId":"1651247740.133346000", + "topicId":"0.0.34352381", + "relationships":[ + "1651247655.671887000" + ], + "__sourceTag__":"issue_requests_source(need_approve)" + } + ], + "blocks":[ + + ], + "commonAddons":[ + { + "id":"03aa71e0-8c5c-4685-aac4-250f4bd72206", + "blockType":"documentsSourceAddon" + }, + { + "id":"cdcf0d38-f2a0-4678-95bb-5489d65b3dec", + "blockType":"documentsSourceAddon" + } + ], + "fields":[ + { + "title":"Organization Name", + "name":"document.credentialSubject.0.field2.field0", + "type":"text" + }, + { + "title":"Production Period Start Date", + "name":"document.credentialSubject.0.field6", + "type":"text" + }, + { + "title":"Production Period End Date", + "name":"document.credentialSubject.0.field8", + "type":"text" + }, + { + "title":"Total kWh Produced in this period", + "name":"document.credentialSubject.0.field7", + "type":"text" + }, + { + "title":"Date", + "name":"document.issuanceDate", + "type":"text" + }, + { + "name":"option.status", + "title":"Operation", + "type":"text", + "width":"250px", + "bindGroup":"issue_requests_source(approved)", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"" + }, + { + "title":"Operation", + "name":"option.status", + "tooltip":"", + "type":"block", + "action":"", + "url":"", + "dialogContent":"", + "dialogClass":"", + "dialogType":"", + "bindBlock":"approve_issue_requests_btn", + "width":"250px", + "bindGroup":"issue_requests_source(need_approve)" + }, + { + "name":"document", + "title":"Document", + "tooltip":"", + "type":"button", + "action":"dialog", + "content":"View Document", + "uiClass":"link", + "dialogContent":"VC", + "dialogClass":"", + "dialogType":"json" + } + ] +} + +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Approve Issue) + +BLOCK approve\_issue\_requests\_btn + +{% swagger method="post" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Approving Issue" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/4185c3b7-f200-4219-a503-17c84fea752f +{% endswagger-description %} + +{% swagger-parameter in="body" name="id" %} +626bf9e1d24497fe1b1e4148 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="owner" %} +did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hash" %} +9Ny3w8HaH6ukaUnRgKrdWadbRM1by5rgn2nS8MQLJipm +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="document" %} + + + "id":"e676b23e-61b9-4243-98fc-349fd9708d67", + + "type":\[ + + "VerifiableCredential" + + ], + + "issuer":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "issuanceDate":"2022-04-29T14:44:38.373Z", + + "@context":\[ + + "https://www.w3.org/2018/credentials/v1" + + ], + + "credentialSubject":\[ + + { + + "field0":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316", + + "field1":"did:hedera:testnet:2PNs5TABEKMm7WNMSLrFQDSaBqkhppjPqcj9ovkbzkrq;hedera:testnet:tid=0.0.34350724", + + "field2":{ + + "field0":"Organization Name", + + "field1":"Address line 1", + + "field2":"Address line 2", + + "field3":"Address line 3", + + "field4":"Postal code", + + "field5":"Country", + + "field6":"Contact person", + + "field7":"test@mail.ru", + + "field8":"Telephone", + + "field9":"Fax", + + "field10":"Existing I-REC Registry organization(s) to become subsidiary", + + "type":"56ce048d-8e24-4aec-b76d-802688f651e8", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ] + + }, + + "field3":{ + + "field0":"Device Name", + + "field1":"Address", + + "field2":"Postal code", + + "field3":"Country", + + "field4":"Longitude", + + "field5":"Latitude", + + "field6":"TSO’s ID for measurement point", + + "field7":1, + + "field8":1, + + "field9":"2022-04-29", + + "field10":"Owner of the network to which the Production Device is connected and the voltage of that connection", + + "field11":"If the Production Device is not connected directly to the grid, specify the circumstances, and additional relevant meter registration numbers", + + "field12":"Expected form of volume evidence", + + "field13":"If other please specify", + + "type":"fd49e6e4-58d7-425a-9518-9a2c4a178b15", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ] + + }, + + "field4":" labeling scheme(s)", + + "field5":"2022-04-29", + + "field6":"2022-04-29", + + "field7":1, + + "field8":"2022-04-29", + + "field9":1, + + "field10":"Type a: Settlement Metering data", + + "field11":"Type b: Non-settlement Metering data", + + "field12":"Type c: Measured Volume Transfer documentation", + + "field13":"Type d: Other", + + "field14":true, + + "field15":true, + + "field16":true, + + "field17":"Installer", + + "field18":"0.0.34235315", + + "ref":"did:hedera:testnet:2PNs5TABEKMm7WNMSLrFQDSaBqkhppjPqcj9ovkbzkrq;hedera:testnet:tid=0.0.34350724", + + "policyId":"626bf178d24497fe1b1e4139", + + "@context":\[ + + "https://ipfs.io/ipfs/bafkreigth2xnezvhywqijetrzvi6czxvfduyfn5f7cbln7n5u6kds2vypq" + + ], + + "id":"a69c8c0e-6fcd-4c63-b4a6-57b44cff63db", + + "type":"88f6b2ad-5945-4086-b15c-8181654948c8&1.0.0" + + } + + ], + + "proof":{ + + "type":"Ed25519Signature2018", + + "created":"2022-04-29T14:44:38Z", + + "verificationMethod":"did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316#did-root-key", + + "proofPurpose":"assertionMethod", + + "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..rEWtgLl9X\_t2EdAYZhKE2ITptj9wEnihu1DhDPLoBBVZN7aV-bgedyDYYOLigPxV580gfm6NJztq\_wXFC4noAA" + + } + + }, + + +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="createDate" %} +2022-04-29T14:44:49.331Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="updateDate" %} +2022-04-29T14:44:49.331Z +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="hederaStatus" %} +ISSUE +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="signature" %} +0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="type" %} +issue_request +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="policyId" %} +626bf178d24497fe1b1e4139 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="tag" %} +create_issue_request +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="option" %} +{ + + "status":"Approved" + + }, +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="schema" %} +\#88f6b2ad-5945-4086-b15c-8181654948c8&1.0.0 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="messageId" %} +1651243487.331059459 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="topicId" %} +0.0.34350746 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="relationships" %} +\[ + + "1651243356.729744000" + + ], +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="__sourceTag__" %} +issue_requests_source(need_approve) +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} + +### Root Authority (Get TrustChain) + +BLOCK trustChainBlock + +{% swagger method="get" path="" baseUrl="/policies/{policyId}/blocks/{blockId}" summary="Displaying TrustChain" %} +{% swagger-description %} +/policies/626bf178d24497fe1b1e4139/blocks/61235b3d-b793-4363-b51d-62df371493cd +{% endswagger-description %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyBlockData' +} +``` +{% endswagger-response %} + +{% swagger-response status="401: Unauthorized" description="Unauthorized" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="403: Forbidden" description="Forbidden" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} diff --git a/docs/demo-guide/demo-usage-guide.md b/docs/demo-guide/demo-usage-guide.md index bd9026d826..09ecf7db8c 100644 --- a/docs/demo-guide/demo-usage-guide.md +++ b/docs/demo-guide/demo-usage-guide.md @@ -121,7 +121,7 @@ After selecting the Installer role, we will see the form that is based on the im 13\. Navigate to the **Tokens** tab and click on the blue people icon on the far right. This view shows the Root Authority all of the users who have been associated with the tokens the Root Authority created. We will now click the **Grant KYC** button. -![](<../.gitbook/assets/DUG\_19 (1).png>) +![](../.gitbook/assets/DUG\_19.png) 14\. We can now log out of the Root Authority account and back in as the Installer. Navigate to the **Policies** tab and click the **Open** button on the far right. The next Policy Workflow Action required by the Installer is to register their sensors. Click the **New Sensors** button, fill out the required information in the dialog box, and select **OK**. diff --git a/docs/demo-guide/demo-using-apis.md b/docs/demo-guide/demo-using-apis.md index 3267eb328b..d3dc84b282 100644 --- a/docs/demo-guide/demo-using-apis.md +++ b/docs/demo-guide/demo-using-apis.md @@ -28,7 +28,7 @@ ### 1.2 In the policy config there is a root block which is the top of the structure -![](<../.gitbook/assets/API\_1 (1).png>) +![](../.gitbook/assets/API\_1.png) ### 1.3 Request the config for the root block @@ -297,7 +297,7 @@ Years of registration {% endswagger-response %} {% endswagger %} -![](../.gitbook/assets/API\_5.png) +![](<../.gitbook/assets/image (6) (1).png>) ## 2. Login as a Root Authority @@ -473,7 +473,7 @@ POST /api/v1/policies/621376c8e6763a0014fb0de4/blocks/6f0f37c0-b62b-4be5-b1d0-e ![](../.gitbook/assets/API\_7.png) -![](../.gitbook/assets/API\_8.png) +![](<../.gitbook/assets/image (2) (1).png>) ## 3. Login as the User @@ -699,9 +699,9 @@ capacity {% endswagger-parameter %} {% endswagger %} -![](../.gitbook/assets/API\_9.png) +![](../.gitbook/assets/Sensor.png) -![](../.gitbook/assets/API\_10.png) +![](../.gitbook/assets/image.png) ### 3.4 Refresh the Blocks @@ -717,4 +717,43 @@ record in the grid (data[0]) {% endswagger-parameter %} {% endswagger %} -![](../.gitbook/assets/API\_11.png) +![](<../.gitbook/assets/image (15) (1).png>) + +### 3.6 Sample MRV Sender Data + +{% swagger method="post" path="" baseUrl="/external" summary="Sending MRV Data" %} +{% swagger-description %} +Sending MRV Data +{% endswagger-description %} + +{% swagger-parameter in="body" name="document" %} +"id":"8d8e8a0a-211d-4180-8001-2e30cd7b915f", "type":[ "VerifiableCredential" ], "issuer":"did:hedera:testnet:3G7JYDvL5QsbBz5u9531UyMKWPJHdDQ5B6nRMK3zqoUm;hedera:testnet:tid=0.0.34404759", "issuanceDate":"2022-05-05T12:30:14.909Z", "@context":[ "https://www.w3.org/2018/credentials/v1" ], "credentialSubject":[ { "type":"5b4cdcee-ba73-4234-bddd-2988b050552c&1.0.0", "@context":[ "https://ipfs.io/ipfs/bafkreiaihnzlo7ahhr6wqnnyqprrl7onqdogkfzyum6poixba5ptjptowu" ], "field0":"2", "field1":"8", "field2":"1", "policyId":"6273c027d79555ef171b550d", "accountId":"0.0.34235315" } ], "proof":{ "type":"Ed25519Signature2018", "created":"2022-05-05T12:30:14Z", "verificationMethod":"did:hedera:testnet:3G7JYDvL5QsbBz5u9531UyMKWPJHdDQ5B6nRMK3zqoUm;hedera:testnet:tid=0.0.34404759#did-root-key", "proofPurpose":"assertionMethod", "jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..awGmfcQzVefihEkoLT7zrqltRoEkuluVV8PALFc7ftlOckY0K7wQOwmdZMG479IZ1g4mW0todYmcLueNgTruAQ" } +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="owner" %} +did:hedera:testnet:CV94CdDeDK5J361y1ocNMVxVbYjRZvSJChDkKCz88my;hedera:testnet:tid=0.0.34235316 +{% endswagger-parameter %} + +{% swagger-parameter in="body" name="policyTag" %} +Tag_1651752987100 +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} diff --git a/docs/demo-guide/irec-demo-guide.md b/docs/demo-guide/irec-demo-guide.md index a99245fdea..5d92d0a3f8 100644 --- a/docs/demo-guide/irec-demo-guide.md +++ b/docs/demo-guide/irec-demo-guide.md @@ -1,6 +1,6 @@ # iREC Demo Guide -This folder contains sample files that are referenced in the Demo Usage Guide +This folder contains a sample file that is referenced in the Demo Guide 1. New iREC Policy ([iRec Policy 2.zip)](https://github.com/hashgraph/guardian/blob/main/Demo%20Artifacts/iRec%20Policy%202.zip) @@ -9,11 +9,11 @@ This folder contains sample files that are referenced in the Demo Usage Guide&#x 1. Issuer (Root Authority) 2. Participant -2\. After running the installation commands, open a tab on your browser and navigate to [http://localhost:3000/](http://localhost:3000). Typically, the way we start the reference implementation demonstration is by logging in as the Verra. Click the Demo Admin Panel drop-down located in the upper right-hand corner of the login screen and select the Issuer user. +2\. After running the installation commands, open a tab on your browser and navigate to [http://localhost:3000/](http://localhost:3000/). Typically, the way we start the reference implementation demonstration is by logging in as an Issuer. Click the Demo Admin Panel drop-down located in the upper right-hand corner of the login screen and select the Issuer user. 3\. You will now be prompted to configure your Issuer account. Press the Generate button to generate a Hedera Operator ID and an Operator Key and enter the name of your Root Authority. Press Connect when finished. This will now create Hedera Consensus Service Topics, fill the account with test hBar, create a DID document, create a Verifiable Credential, etc. -![](<../.gitbook/assets/iREC\_0 (1).png>) +![](<../.gitbook/assets/Verra\_2 (1).png>) 4\. This could be one of the most interesting parts of the reference implementation. Now we will be creating the Policy. We have two ways to "create policies." The first way is to import an existing policy. This is the easiest way to get started. When you import a policy, all schemas and tokens that are required in the policy are automatically populated. To do this, you can use the sample policy that we have already uploaded to IPFS by entering the Hedera Message IDs. @@ -23,11 +23,11 @@ This folder contains sample files that are referenced in the Demo Usage Guide&#x ![](../.gitbook/assets/iREC\_1.png) -![](../.gitbook/assets/iREC\_2.2.png) +![](<../.gitbook/assets/iREC\_2.2 (1).png>) 5\. Click on Issuer’s profile icon and select "Log Out." We will now go back into the Admin Panel. This time we will select Registrant. -6\. Now, we can click on the Policies tab. This is where the specific actions required by the Policy Workflow will be found. We can click the Open button to the right of the Verra Policy, the Issuer created. This is where the custom user will be able to assign the role that was created by Issuer during the workflow creation process. In our case, we created the custom role of Registrant so the user will need to select the Registrant role from the drop down. +6\. Now, we can click on the Policies tab. This is where the specific actions required by the Policy Workflow will be found. We can click the Open button to the right of the iREC Policy, the Issuer created. This is where the custom user will be able to assign the role that was created by Issuer during the workflow creation process. In our case, we created the custom role of Registrant so the user will need to select the Registrant role from the drop down. ![](../.gitbook/assets/iREC\_3.png) @@ -71,7 +71,7 @@ For now, we will be adding it manually, but in future, we will be automating the ![](../.gitbook/assets/iREC\_13.png) -After submitting the data, the Registrant is waiting for approval from the iREC. +After submitting the data, the Registrant is waiting for approval from the Issuer. ![](../.gitbook/assets/iREC\_14.png) @@ -89,7 +89,7 @@ After submitting the data, the Registrant is waiting for approval from the iREC. 16\. We can also check Token History by logging back as Issuer. -![](../.gitbook/assets/iREC\_17.png) +![](<../.gitbook/assets/iREC\_17 (1).png>) We have the option of viewing TrustChain. You can view TrustChain by clicking on View TrustChain button. diff --git a/docs/demo-guide/verra-redd+-demo-guide.md b/docs/demo-guide/verra-redd+-demo-guide.md index e453c63d52..86e50aa33c 100644 --- a/docs/demo-guide/verra-redd+-demo-guide.md +++ b/docs/demo-guide/verra-redd+-demo-guide.md @@ -1,6 +1,6 @@ # Verra Redd+ Demo Guide -This folder contains sample files that are referenced in the Demo Usage Guide +This folder contains a sample file that is referenced in the Demo Usage Guide 1. Sample of Verra REDD Policy (Verra REDD.zip) 2. Sample Schema design template for Verra REDD Policy (REDD APD Schema Design Template.xlsx) @@ -11,7 +11,7 @@ This folder contains sample files that are referenced in the Demo Usage Guide&#x * **Project Proponent** * **VVB** -2\. After running the installation commands, open a tab on your browser and navigate to [http://localhost:3000/](http://localhost:3000). Typically, the way we start the reference implementation demonstration is by logging in as the Verra. Click the Demo Admin Panel drop-down located in the upper right-hand corner of the login screen and select the Verra user. +2\. After running the installation commands, open a tab on your browser and navigate to [http://localhost:3000/](http://localhost:3000/). Typically, the way we start the reference implementation demonstration is by logging in as Verra. Click the Demo Admin Panel drop-down located in the upper right-hand corner of the login screen and select the Verra user. ![](../.gitbook/assets/Verra\_1.png) @@ -29,7 +29,7 @@ Once you have done that, you can move onto the next step. 5\. Click on Verra's profile icon and select "Log Out." We will now go back into the Admin Panel. This time we will select VVB. -6\. Now, we can click on the Policies tab. This is where the specific actions required by the Policy Workflow will be found. We can click the Open button to the right of the Verra Policy, the Verra created. +6\. Now, we can click on the Policies tab. This is where the specific actions required by the Policy Workflow will be found. We can click Open button to the right of the Verra Policy, the Verra created. ![](../.gitbook/assets/Verra\_3.png) diff --git a/docs/external-apis/sends-data-from-external-source.md b/docs/external-apis/sends-data-from-external-source.md new file mode 100644 index 0000000000..4cb660173e --- /dev/null +++ b/docs/external-apis/sends-data-from-external-source.md @@ -0,0 +1,30 @@ +# Sends Data from External Source + +{% swagger method="post" path="" baseUrl="/external" summary="Sends data from an external source." %} +{% swagger-description %} +Sends data from an external source +{% endswagger-description %} + +{% swagger-parameter in="body" name="Object" required="true" %} +Object that contains VC Document +{% endswagger-parameter %} + +{% swagger-response status="200: OK" description="Successful Operation" %} +```javascript +{ + // Response +} +``` +{% endswagger-response %} + +{% swagger-response status="500: Internal Server Error" description="Internal Server Error" %} +```javascript +{ + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +} +``` +{% endswagger-response %} +{% endswagger %} diff --git a/docs/getting-started/built-with.md b/docs/getting-started/built-with.md index b6e6de6fc5..3602e9e57f 100644 --- a/docs/getting-started/built-with.md +++ b/docs/getting-started/built-with.md @@ -1,18 +1,18 @@ -# Built With +# Frameworks/Libraries The Guardian solution is built with the following major frameworks/libraries. **Backend** -* [NodeJS](https://nodejs.org) -* [MongoDB](https://www.mongodb.com) -* [Express](https://expressjs.com) -* [FastMQ](https://www.npmjs.com/package/fastmq) -* [TypeORM](https://typeorm.io) +* [NodeJS](https://nodejs.org/) +* [MongoDB](https://www.mongodb.com/) +* [Express](https://expressjs.com/) +* [Nats](https://nats.io/) +* [TypeORM](https://typeorm.io/) * [Hedera-DID-JS-SDK](https://github.com/hashgraph/did-sdk-js) * [W3C VC-JS-HTTP](https://w3c.github.io/vc-data-model/) **Frontend** -* [Angular](https://angular.io) +* [Angular](https://angular.io/) * [crypto-browserify](https://www.npmjs.com/package/crypto-browserify) diff --git a/docs/getting-started/contact.md b/docs/getting-started/contact.md index 13ee53cf07..0a7a0f9dab 100644 --- a/docs/getting-started/contact.md +++ b/docs/getting-started/contact.md @@ -2,5 +2,5 @@ For any questions, please reach out to the Envision Blockchain Solutions team at: -* Website: <[www.envisionblockchain.com](http://www.envisionblockchain.com)> +* Website: <[www.envisionblockchain.com](http://www.envisionblockchain.com/)> * Email: [info@envisionblockchain.com](mailto:info@envisionblockchain.com) diff --git a/docs/getting-started/getting-started/installation.md b/docs/getting-started/getting-started/installation.md index 40bddcdec2..6f44fd8802 100644 --- a/docs/getting-started/getting-started/installation.md +++ b/docs/getting-started/getting-started/installation.md @@ -232,3 +232,25 @@ To run **message-broker** unit tests, following commands needs to be executed: cd message-broker npm run test ``` + +### Summary of URLs and Ports + +#### Using Docker: + +| Folder | URL | +| -------------- | -------------------------------------------------------------------------- | +| WEB\_INTERFACE | [http://localhost:3000](http://localhost:3000) | +| API\_GATEWAY | [http://localhost:3000/api/v1/](http://localhost:3000/api/v1/) | +| MRV\_SENDER | [http://localhost:3000/mrv-sender/](http://localhost:3000/mrv-sender/) | +| TOPIC\_VIEWER | [http://localhost:3000/topic-viewer/](http://localhost:3000/topic-viewer/) | +| API\_DOCS | [http://localhost:3000/api-docs/v1/](ttp://localhost:3000/api-docs/v1/) | + +#### Not in Docker: + +| Folder | URL | +| -------------- | ------------------------------------------------ | +| WEB\_INTERFACE | [http://localhost:4200/](http://localhost:4200/) | +| API\_GATEWAY | [http://localhost:3002/](http://localhost:3002/) | +| MRV\_SENDER | [http://localhost:3005/](http://localhost:3005/) | +| TOPIC\_VIEWER | [http://localhost:3006/](http://localhost:3006/) | +| API\_DOCS | [http://localhost:3001/](http://localhost:3001/) | diff --git a/docs/getting-started/getting-started/prerequisites.md b/docs/getting-started/getting-started/prerequisites.md index 267632f8cc..6d16711652 100644 --- a/docs/getting-started/getting-started/prerequisites.md +++ b/docs/getting-started/getting-started/prerequisites.md @@ -1,6 +1,6 @@ # Prerequisites -* [Docker](https://www.docker.com) (To build with one command) -* [MongoDB](https://www.mongodb.com) and [NodeJS](https://nodejs.org) (If you would like to manually build every component) -* [Hedera Testnet Account](https://portal.hedera.com) +* [Docker](https://www.docker.com/) (To build with one command) +* [MongoDB](https://www.mongodb.com/) , [NodeJS](https://nodejs.org/) and [Nats](https://nats.io/) (If you build with docker these components will be installed automatically) +* [Hedera Testnet Account](https://portal.hedera.com/) * [NFT.Storage Account](https://nft.storage/#getting-started) diff --git a/docs/getting-started/reference-implementation.md b/docs/getting-started/reference-implementation.md index 809db0b71e..fd2bb56aa7 100644 --- a/docs/getting-started/reference-implementation.md +++ b/docs/getting-started/reference-implementation.md @@ -2,4 +2,4 @@ This repo contains a reference implementation of the Guardian to learn how to use the components for various applications. This reference implementation is designed with modularity so that different components may be swapped out based on various implementation requirements. Please see the Guardian's architecture diagram below: -![](https://user-images.githubusercontent.com/40637665/137059380-94303137-b9e4-402c-bb67-9212b6f1c4f4.png) +![](../.gitbook/assets/Guardian\_Architecture\_Diagram.png) diff --git a/docs/policy-creation-using-the-guardian-apis/creation-of-a-policy.md b/docs/policy-creation-using-the-guardian-apis/creation-of-a-policy.md index c86778663e..95d6db93db 100644 --- a/docs/policy-creation-using-the-guardian-apis/creation-of-a-policy.md +++ b/docs/policy-creation-using-the-guardian-apis/creation-of-a-policy.md @@ -11,7 +11,7 @@ Creates a new policy. Only users with the Root Authority role are allowed to mak Object that contains policy configuration. {% endswagger-parameter %} -{% swagger-response status="200: OK" description="Successful operation" %} +{% swagger-response status="201: Created" description="Successful operation" %} {% endswagger-response %} diff --git a/docs/policy-workflow-creation-using-the-guardian-user-interface/getting-started-with-the-policy-workflows.md b/docs/policy-workflow-creation-using-the-guardian-user-interface/getting-started-with-the-policy-workflows.md index 272522e44f..f1f3fe3f27 100644 --- a/docs/policy-workflow-creation-using-the-guardian-user-interface/getting-started-with-the-policy-workflows.md +++ b/docs/policy-workflow-creation-using-the-guardian-user-interface/getting-started-with-the-policy-workflows.md @@ -18,7 +18,7 @@ Once we have created the Draft of the policy – notice the status field showing The edit screen will open and you will notice two boxes on the right side of the screen. The top Policy box is static and offers the ability to add high-level “Policy properties.” You can edit the name, Policy Tag, etc. Note that you can also create custom roles that are specific to your policy. -![](../.gitbook/assets/PW\_4.png) +![](<../.gitbook/assets/image (18).png>) The second Interface ContainerBlock is specific to the first workflow block. We will begin editing this block to build our policy! diff --git a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-1.md b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-1.md index 2f62b0fdb0..db093c155e 100644 --- a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-1.md +++ b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-1.md @@ -12,7 +12,7 @@ We then select “Default Active” as true since this policy action must always Now we have a Policy Action defined, however, without any specific actions -![](../.gitbook/assets/PW\_6.png) +![](<../.gitbook/assets/PW\_6 (1).png>) **Programmatically this workflow step looks like this:** diff --git a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-12.md b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-12.md index 2966370863..069af64aee 100644 --- a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-12.md +++ b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-12.md @@ -4,7 +4,7 @@ We then click back to the “sensors\_page” button on the left side to add a We name the tag, add permissions – again installer since this action will still be performed by the installer, select the UI type as “Blank” and set the cyclic flag since we want to add more than one sensor to the grid. -![](../.gitbook/assets/PW\_17.3.png) +![](../.gitbook/assets/PW\_17.png) **Programmatically this workflow step looks like this:** diff --git a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-21.md b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-21.md index b5769547b7..43317e29d4 100644 --- a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-21.md +++ b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-21.md @@ -8,7 +8,7 @@ Note that for the approve option we are binding the action to the “update\_app Note that for the reject option we are binding the action to the “installer\_rejected” action we previously defined. -![](../.gitbook/assets/PW\_26.png) +![](<../.gitbook/assets/PW\_26 (1).png>) Next, we return to the “approve\_documents\_grid” step and add the “approve\_documents\_btn” action as a binding block to Field 4 since Field 4 captures the approval or rejection of the document. Note, the choice of block for Field 4 makes sense now, because the bound action is a block itself. diff --git a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-5.md b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-5.md index f45a645d6b..e84020e331 100644 --- a/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-5.md +++ b/docs/policy-workflow-creation-using-the-guardian-user-interface/policy-workflow-step-5.md @@ -6,7 +6,7 @@ Again we need a Send step since we need to send the approval we obtained from th We now proceed as with the previous “Send” step “save\_new\_approve\_document” to configure the policy action step. -![](../.gitbook/assets/PW\_10.png) +![](<../.gitbook/assets/PW\_10 (1).png>) **Programmatically this workflow step looks like this:** diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1afe53c240..f07597a570 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "guardian", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "guardian", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "@angular-material-components/datetime-picker": "^6.0.3", @@ -29,11 +29,13 @@ "@transmute/security-context": "^0.7.0-unstable.5", "@transmute/vc.js": "^0.7.0-unstable.5", "codemirror": "^5.65.0", + "cronstrue": "^2.4.0", "crypto-browserify": "^3.12.0", "file-saver": "^2.0.5", "interfaces": "file:../interfaces", "js-yaml": "^4.1.0", "moment": "^2.29.1", + "ngx-file-drop": "^12.0.0", "ngx-toastr": "^14.1.0", "process": "^0.11.10", "rxjs": "~6.6.0", @@ -59,7 +61,7 @@ } }, "../interfaces": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" @@ -5413,6 +5415,11 @@ "node": ">=8" } }, + "node_modules/cronstrue": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.4.0.tgz", + "integrity": "sha512-KDJgE8XoT0Nupt1iljNGAQnxkfITwIYkL7mHrzH4a0AWyrj7Xk6GVCNPN3Avs7tU2yYoNuDculMKp9T3jysbPA==" + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -10953,6 +10960,22 @@ "node": ">=4" } }, + "node_modules/ngx-file-drop": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-12.0.0.tgz", + "integrity": "sha512-ywoKbGLX4rPc9cNfAKpSl1YhFcx9qB56XrcQHL1vkJ0WSwDYFo8CIpy2iCjFXqOyY+03NkRIb8d8RIDS+ZMv7Q==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 6.9.0" + }, + "peerDependencies": { + "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0" + } + }, "node_modules/ngx-toastr": { "version": "14.2.2", "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-14.2.2.tgz", @@ -22657,6 +22680,11 @@ } } }, + "cronstrue": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.4.0.tgz", + "integrity": "sha512-KDJgE8XoT0Nupt1iljNGAQnxkfITwIYkL7mHrzH4a0AWyrj7Xk6GVCNPN3Avs7tU2yYoNuDculMKp9T3jysbPA==" + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -26934,6 +26962,14 @@ } } }, + "ngx-file-drop": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ngx-file-drop/-/ngx-file-drop-12.0.0.tgz", + "integrity": "sha512-ywoKbGLX4rPc9cNfAKpSl1YhFcx9qB56XrcQHL1vkJ0WSwDYFo8CIpy2iCjFXqOyY+03NkRIb8d8RIDS+ZMv7Q==", + "requires": { + "tslib": "^2.0.0" + } + }, "ngx-toastr": { "version": "14.2.2", "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-14.2.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 682f9484f1..cba36f3c69 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,11 +21,13 @@ "@transmute/security-context": "^0.7.0-unstable.5", "@transmute/vc.js": "^0.7.0-unstable.5", "codemirror": "^5.65.0", + "cronstrue": "^2.4.0", "crypto-browserify": "^3.12.0", "file-saver": "^2.0.5", "interfaces": "file:../interfaces", "js-yaml": "^4.1.0", "moment": "^2.29.1", + "ngx-file-drop": "^12.0.0", "ngx-toastr": "^14.1.0", "process": "^0.11.10", "rxjs": "~6.6.0", @@ -53,11 +55,12 @@ "name": "guardian", "private": true, "scripts": { + "dev:docker": "ng serve --host 0.0.0.0 --disable-host-check --proxy-config ./proxy.docker.json", "build": "ng build", "ng": "ng", "start": "ng serve --proxy-config ./proxy.conf.json", "test": "ng test", "watch": "ng build --watch --configuration development --output-path ../www-data" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/frontend/proxy.docker.json b/frontend/proxy.docker.json new file mode 100644 index 0000000000..7be5c029d5 --- /dev/null +++ b/frontend/proxy.docker.json @@ -0,0 +1,22 @@ +{ + "/api/v1/*": { + "target": "http://api-gateway:3002/", + "secure": false, + "logLevel": "debug", + "changeOrigin": true, + "ws": false, + "pathRewrite": { + "/api/v1": "" + } + }, + "/ws/*": { + "target": "http://api-gateway:3002/", + "secure": false, + "ws": true, + "logLevel": "debug", + "changeOrigin": true, + "pathRewrite": { + "/ws": "" + } + } +} diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index c38e09c2c5..83b7ff33ec 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -23,128 +23,129 @@ import { StatusService } from './services/status.service'; class Guard { - private router: Router; - private auth: AuthService; - private role: UserRole; - private defaultPage: string; - - constructor( - router: Router, - auth: AuthService, - role: UserRole, - defaultPage: string - ) { - this.router = router; - this.auth = auth - this.role = role; - this.defaultPage = defaultPage - } - - canActivate() { - return this.auth.sessions().pipe( - map((res: IUser | null) => { - if (res) { - return res.role == this.role; - } else { - return this.router.parseUrl(this.defaultPage); - } - }), - catchError(() => { - return of(this.router.parseUrl(this.defaultPage)); - }) - ) - } - - canActivateChild() { - return this.auth.sessions().pipe( - map((res: IUser | null) => { - if (res) { - return res.role == this.role; - } else { - return this.router.parseUrl(this.defaultPage); - } - }), - catchError(() => { - return of(this.router.parseUrl(this.defaultPage)); - }) - ) - } + private router: Router; + private auth: AuthService; + private role: UserRole; + private defaultPage: string; + + constructor( + router: Router, + auth: AuthService, + role: UserRole, + defaultPage: string + ) { + this.router = router; + this.auth = auth + this.role = role; + this.defaultPage = defaultPage + } + + canActivate() { + return this.auth.sessions().pipe( + map((res: IUser | null) => { + if (res) { + return res.role == this.role; + } else { + return this.router.parseUrl(this.defaultPage); + } + }), + catchError(() => { + return of(this.router.parseUrl(this.defaultPage)); + }) + ) + } + + canActivateChild() { + return this.auth.sessions().pipe( + map((res: IUser | null) => { + if (res) { + return res.role == this.role; + } else { + return this.router.parseUrl(this.defaultPage); + } + }), + catchError(() => { + return of(this.router.parseUrl(this.defaultPage)); + }) + ) + } } @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class UserGuard extends Guard implements CanActivate { - constructor(router: Router, auth: AuthService) { - super(router, auth, UserRole.USER, '/login'); - } + constructor(router: Router, auth: AuthService) { + super(router, auth, UserRole.USER, '/login'); + } } @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class RootAuthorityGuard extends Guard implements CanActivate { - constructor(router: Router, auth: AuthService) { - super(router, auth, UserRole.ROOT_AUTHORITY, '/login'); - } + constructor(router: Router, auth: AuthService) { + super(router, auth, UserRole.ROOT_AUTHORITY, '/login'); + } } @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class AuditorGuard extends Guard implements CanActivate { - constructor(router: Router, auth: AuthService) { - super(router, auth, UserRole.AUDITOR, '/login'); - } + constructor(router: Router, auth: AuthService) { + super(router, auth, UserRole.AUDITOR, '/login'); + } } @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class ServicesStatusGuard implements CanActivate { - constructor( - private router: Router, - private status: StatusService - ) { - } - - canActivate() { - return this.status.IsServicesReady().pipe( - map(item => item || this.router.parseUrl('/status')) - ); - } + constructor( + private router: Router, + private status: StatusService + ) { + } + + canActivate() { + return this.status.IsServicesReady().pipe( + map(item => item || this.router.parseUrl('/status')) + ); + } } const routes: Routes = [ - { path: 'login', component: LoginComponent }, - { path: 'register', component: RegisterComponent }, - - { path: 'user-profile', component: UserProfileComponent, canActivate: [UserGuard, ServicesStatusGuard] }, - - { path: 'config', component: RootConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, - { path: 'tokens', component: TokenConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, - { path: 'schemes', component: SchemaConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, - { path: 'admin', component: AdminHeaderComponent, canActivate: [RootAuthorityGuard], canActivateChild: [RootAuthorityGuard], - children: [ - { path: 'status', component: ServiceStatusComponent }, - { path: 'settings', component: SettingsViewComponent, canActivate: [ServicesStatusGuard]}, - { path: 'logs', component: LogsViewComponent, canActivate: [ServicesStatusGuard]} - ] - }, - { path: 'status', component: ServiceStatusComponent }, - { path: 'audit', component: AuditComponent, canActivate: [AuditorGuard, ServicesStatusGuard] }, - { path: 'trust-chain', component: TrustChainComponent, canActivate: [AuditorGuard, ServicesStatusGuard] }, - - { path: 'policy-viewer', component: PolicyViewerComponent, canActivate: [ServicesStatusGuard] }, - { path: 'policy-configuration', component: PolicyConfigurationComponent, canActivate: [ServicesStatusGuard] }, - - { path: '', component: HomeComponent }, - { path: '**', redirectTo: '', pathMatch: 'full' }, + { path: 'login', component: LoginComponent }, + { path: 'register', component: RegisterComponent }, + + { path: 'user-profile', component: UserProfileComponent, canActivate: [UserGuard, ServicesStatusGuard] }, + + { path: 'config', component: RootConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, + { path: 'tokens', component: TokenConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, + { path: 'schemes', component: SchemaConfigComponent, canActivate: [RootAuthorityGuard, ServicesStatusGuard] }, + { + path: 'admin', component: AdminHeaderComponent, canActivate: [RootAuthorityGuard], canActivateChild: [RootAuthorityGuard], + children: [ + { path: 'status', component: ServiceStatusComponent }, + { path: 'settings', component: SettingsViewComponent, canActivate: [ServicesStatusGuard] }, + { path: 'logs', component: LogsViewComponent, canActivate: [ServicesStatusGuard] } + ] + }, + { path: 'status', component: ServiceStatusComponent }, + { path: 'audit', component: AuditComponent, canActivate: [AuditorGuard, ServicesStatusGuard] }, + { path: 'trust-chain', component: TrustChainComponent, canActivate: [AuditorGuard, ServicesStatusGuard] }, + + { path: 'policy-viewer', component: PolicyViewerComponent, canActivate: [ServicesStatusGuard] }, + { path: 'policy-configuration', component: PolicyConfigurationComponent, canActivate: [ServicesStatusGuard] }, + + { path: '', component: HomeComponent }, + { path: '**', redirectTo: '', pathMatch: 'full' }, ]; @NgModule({ - imports: [RouterModule.forRoot(routes, { useHash: false })], - exports: [RouterModule] + imports: [RouterModule.forRoot(routes, { useHash: false })], + exports: [RouterModule] }) export class AppRoutingModule { } diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index a56a02206e..80d5cb95ac 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -1,7 +1,7 @@
-
- -
- -
+
+ +
+ +
\ No newline at end of file diff --git a/frontend/src/app/app.component.scss b/frontend/src/app/app.component.scss index 43d40da7bf..2b07058525 100644 --- a/frontend/src/app/app.component.scss +++ b/frontend/src/app/app.component.scss @@ -4,11 +4,12 @@ background: none !important; } -::ng-deep .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title { - color: rgba(0,0,0,.87) !important; +::ng-deep .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-title { + color: rgba(0, 0, 0, .87) !important; } -::ng-deep .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description { - color: rgba(0,0,0,.54) !important; + +::ng-deep .mat-expansion-panel-header[aria-disabled=true] .mat-expansion-panel-header-description { + color: rgba(0, 0, 0, .54) !important; } .content { @@ -53,7 +54,7 @@ body { mat-dialog-container { padding: 0px; } - + .g-dialog-header { height: 90px; padding: 22px; @@ -130,7 +131,7 @@ body { } } } - + .g-dialog-body { padding: 12px 14px 0px 20px; max-height: calc(100vh - 300px); @@ -155,6 +156,6 @@ body { border-color: rgb(0 0 0 / 40%); } -::ng-deep .CodeMirror { - height: auto !important; +::ng-deep .CodeMirror { + height: auto !important; } \ No newline at end of file diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts index 907cc4362e..440fa25966 100644 --- a/frontend/src/app/app.component.spec.ts +++ b/frontend/src/app/app.component.spec.ts @@ -3,33 +3,33 @@ import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], - }).compileComponents(); - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + }); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'guardian'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('guardian'); - }); + it(`should have as title 'guardian'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('guardian'); + }); - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain('guardian app is running!'); - }); + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(compiled.querySelector('.content span').textContent).toContain('guardian app is running!'); + }); }); diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 584482ccc4..74d6197460 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -39,6 +39,8 @@ import { SettingsViewComponent } from './views/admin/settings-view/settings-view import { IconPreviewDialog } from './components/icon-preview-dialog/icon-preview-dialog.component'; import { DetailsLogDialog } from './views/admin/details-log-dialog/details-log-dialog.component'; import { ServiceStatusComponent } from './views/admin/service-status/service-status.component'; +import { CommonComponentsModule } from './common-components.module'; +import { ConfirmationDialogComponent } from './components/confirmation-dialog/confirmation-dialog.component'; @NgModule({ declarations: [ @@ -60,11 +62,13 @@ import { ServiceStatusComponent } from './views/admin/service-status/service-sta AdminHeaderComponent, IconPreviewDialog, DetailsLogDialog, - ServiceStatusComponent + ServiceStatusComponent, + ConfirmationDialogComponent ], imports: [ BrowserModule, CommonModule, + CommonComponentsModule, MaterialModule, AppRoutingModule, BrowserAnimationsModule, diff --git a/frontend/src/app/common-components.module.ts b/frontend/src/app/common-components.module.ts new file mode 100644 index 0000000000..5ba027bf75 --- /dev/null +++ b/frontend/src/app/common-components.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MaterialModule } from './material.module'; +import { DatetimePicker } from './components/datetime-picker/datetime-picker.component'; +import { Dragonglass } from './components/dragonglass/dragonglass.component'; +import { NgxMatDateFormats, NgxMatDatetimePickerModule, NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker'; + +@NgModule({ + declarations: [ + DatetimePicker, + Dragonglass + ], + imports: [ + CommonModule, + MaterialModule, + NgxMatDatetimePickerModule + ], + exports: [ + DatetimePicker, + Dragonglass + ] +}) +export class CommonComponentsModule { } \ No newline at end of file diff --git a/frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.css b/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.css similarity index 100% rename from frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.css rename to frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.css diff --git a/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.html b/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.html new file mode 100644 index 0000000000..0dafe6513e --- /dev/null +++ b/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.html @@ -0,0 +1,6 @@ +

{{dialogTitle}}

+{{dialogText}} + + + + \ No newline at end of file diff --git a/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.ts b/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.ts new file mode 100644 index 0000000000..16b345d6b7 --- /dev/null +++ b/frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.ts @@ -0,0 +1,22 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; + +@Component({ + selector: 'app-confirmation-dialog', + templateUrl: './confirmation-dialog.component.html', + styleUrls: ['./confirmation-dialog.component.css'] +}) +export class ConfirmationDialogComponent implements OnInit { + + public dialogTitle!: string; + public dialogText!: string; + + constructor(@Inject(MAT_DIALOG_DATA) public data: any) { + this.dialogTitle = data.dialogTitle; + this.dialogText = data.dialogText; + } + + ngOnInit(): void { + } + +} diff --git a/frontend/src/app/components/datetime-picker/datetime-picker.component.css b/frontend/src/app/components/datetime-picker/datetime-picker.component.css new file mode 100644 index 0000000000..89b5546199 --- /dev/null +++ b/frontend/src/app/components/datetime-picker/datetime-picker.component.css @@ -0,0 +1,23 @@ +.container { + display: flex; + padding: 0px 0px 0px 5px; +} + +.mat-input-element { + font: inherit; + background: transparent; + color: currentColor; + border: none; + outline: none; + padding: 0; + margin: 0; + width: 100%; + max-width: 100%; + vertical-align: bottom; + text-align: inherit; + box-sizing: content-box; +} + +.container ::ng-deep .mat-icon-button.cdk-program-focused .mat-button-focus-overlay { + opacity: 0; +} \ No newline at end of file diff --git a/frontend/src/app/components/datetime-picker/datetime-picker.component.html b/frontend/src/app/components/datetime-picker/datetime-picker.component.html new file mode 100644 index 0000000000..9ea35d951c --- /dev/null +++ b/frontend/src/app/components/datetime-picker/datetime-picker.component.html @@ -0,0 +1,8 @@ +
+ + + +
\ No newline at end of file diff --git a/frontend/src/app/components/datetime-picker/datetime-picker.component.ts b/frontend/src/app/components/datetime-picker/datetime-picker.component.ts new file mode 100644 index 0000000000..da395967dc --- /dev/null +++ b/frontend/src/app/components/datetime-picker/datetime-picker.component.ts @@ -0,0 +1,63 @@ +import { Component, EventEmitter, Inject, Input, Output, SimpleChanges, ViewChild } from '@angular/core'; +import * as moment from 'moment'; +import { NgxMatDateAdapter, NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker'; +import { NgxMatMomentAdapter } from '@angular-material-components/moment-adapter'; + +export const DATETIME_FORMATS = { + parse: { + dateInput: 'l, LT', + }, + display: { + dateInput: 'DD-MM-YYYY HH:mm (UTC Z)', + monthYearLabel: 'MM yyyy', + dateA11yLabel: 'LL', + monthYearA11yLabel: 'MMMM YYYY', + } +}; + +/** + * Dialog for icon preview. + */ +@Component({ + selector: 'datetime-picker', + templateUrl: './datetime-picker.component.html', + styleUrls: ['./datetime-picker.component.css'], + providers: [ + { provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter }, + { provide: NGX_MAT_DATE_FORMATS, useValue: DATETIME_FORMATS } + ] +}) +export class DatetimePicker { + @Input() placeholder!: string; + @Input() readonly!: boolean; + @Input() value!: string; + @Input() format!: any; + @Output() valueChange = new EventEmitter(); + + private _currentValue!: string; + + public disabled = false; + public showSpinners = true; + public showSeconds = false; + public touchUi = false; + public enableMeridian = true; + public stepHour = 1; + public stepMinute = 5; + public stepSecond = 1; + public defaultTime = [new Date().getHours(), 0, 0] + + constructor() { + } + + ngOnInit() { + this.placeholder = this.placeholder || 'Choose a date & time'; + } + + onValue(event: any) { + this._currentValue = moment(event.value).utc().toISOString(); + if (this.value != this._currentValue) { + this.value = this._currentValue; + this.valueChange.emit(this._currentValue); + } + } +} \ No newline at end of file diff --git a/frontend/src/app/components/dragonglass/dragonglass.component.css b/frontend/src/app/components/dragonglass/dragonglass.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.html b/frontend/src/app/components/dragonglass/dragonglass.component.html similarity index 100% rename from frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.html rename to frontend/src/app/components/dragonglass/dragonglass.component.html diff --git a/frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.ts b/frontend/src/app/components/dragonglass/dragonglass.component.ts similarity index 100% rename from frontend/src/app/policy-engine/helpers/dragonglass/dragonglass.component.ts rename to frontend/src/app/components/dragonglass/dragonglass.component.ts diff --git a/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.css b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.css new file mode 100644 index 0000000000..86613e7257 --- /dev/null +++ b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.css @@ -0,0 +1,12 @@ +::ng-deep .file-drop-zone-content { + height: 200px; + display: flex; + align-items: center; + justify-content: center; +} + +::ng-deep .file-drop-zone { + border: 2px dotted black; + border-radius: 3%; + cursor: pointer; +} \ No newline at end of file diff --git a/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.html b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.html new file mode 100644 index 0000000000..c4c60a07cc --- /dev/null +++ b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.html @@ -0,0 +1,7 @@ + + + + {{dropZoneLabel}} attach_file + + diff --git a/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.ts b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.ts new file mode 100644 index 0000000000..f4d437ed11 --- /dev/null +++ b/frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.ts @@ -0,0 +1,63 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { NgxFileDropEntry } from 'ngx-file-drop'; +import { ToastrService } from 'ngx-toastr'; + +@Component({ + selector: 'app-file-drag-n-drop', + templateUrl: './file-drag-n-drop.component.html', + styleUrls: ['./file-drag-n-drop.component.css'] +}) +export class FileDragNDropComponent implements OnInit { + + @Output() onFileLoaded: EventEmitter = new EventEmitter(); + @Input() dropZoneLabel: string = ""; + + constructor( + private toastr: ToastrService + ) { } + + ngOnInit(): void { + } + + public droppedFile(files: NgxFileDropEntry[]) { + if (files.length > 1) { + this.toastr.error("Cannot add more than 1 files", "File import error", { positionClass: 'toast-bottom-right' }) + } else { + const droppedFile = files[0]; + if (droppedFile.fileEntry.isFile && this.isFileAllowed(droppedFile.fileEntry.name)) { + const fileEntry = droppedFile.fileEntry as any; + fileEntry.file((file: File) => { + this.onFileLoaded.emit(file); + }); + } else { + this.toastr.error("Only files in '.zip' format are accepted", "File import error", { positionClass: 'toast-bottom-right' }); + } + } + } + + public importFromFile() { + const input = document.createElement('input'); + input.type = 'file'; + input.accept = '.zip'; + input.click(); + input.onchange = (e: any) => { + const file = e.target.files[0]; + this.onFileLoaded.emit(file); + } + } + + private isFileAllowed(fileName: string) { + let isFileAllowed = false; + const allowedFiles = ['.zip']; + const regex = /(?:\.([^.]+))?$/; + const extension = regex.exec(fileName); + if (extension) { + for (const ext of allowedFiles) { + if (ext === extension[0]) { + isFileAllowed = true; + } + } + } + return isFileAllowed; + } +} diff --git a/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.css b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.css new file mode 100644 index 0000000000..eb08061d54 --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.css @@ -0,0 +1,86 @@ +.container { + display: flex; + justify-content: space-between; + padding-right: 14px; +} + +.container button { + margin-top: 5px; + margin-left: 10px; + min-width: 280px; +} + +.schema-field { + flex: 1; +} + +:host .content { + max-height: 400px; +} + +.policy-header { + height: 44px; + font-size: 34px; + display: block; + padding: 12px; + box-sizing: border-box; + text-align: center; + color: #000; +} + +.delimiter { + padding: 30px 30px; + width: 100%; + height: 60px; + box-sizing: border-box; + position: relative; +} + +.delimiter::after { + content: ''; + position: absolute; + height: 2px; + top: 30px; + left: 0px; + right: 0px; + border-top: 1px solid #c8c8c8; +} + +.field-value { + color: #000; + font-size: 20px; + margin-bottom: 20px; + max-width: 600px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + margin-left: 8px; +} + +.field-name { + margin-bottom: 12px; +} + +.field { + margin-top: 5px; + margin-bottom: 28px; +} + +.field-last { + margin-bottom: 0px; +} + +.loading { + background: #fff; + position: absolute; + z-index: 99; + left: 0; + bottom: 0; + right: 0; + top: 0; + display: flex; + align-items: center; + justify-items: center; + justify-content: center; + align-content: center; +} diff --git a/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.html b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.html new file mode 100644 index 0000000000..c6af049afc --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.html @@ -0,0 +1,13 @@ +
+
+
+ Code Editor +
+
+ +
+
+
+ +
+
diff --git a/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.ts b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.ts new file mode 100644 index 0000000000..28833d400e --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.ts @@ -0,0 +1,65 @@ +import { + AfterContentChecked, AfterContentInit, + AfterViewChecked, + AfterViewInit, + Component, + Inject, + OnInit, + ViewChild +} from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +/** + * Export schema dialog. + */ +@Component({ + selector: 'code-editor-dialog', + templateUrl: './code-editor-dialog.component.html', + styleUrls: ['./code-editor-dialog.component.css'] +}) +export class CodeEditorDialogComponent implements OnInit, AfterContentInit { + codeMirrorOptions: any = { + theme: 'default', + mode: 'javascript', + styleActiveLine: true, + lineNumbers: true, + lineWrapping: true, + foldGutter: false, + gutters: [ + 'CodeMirror-linenumbers', + ], + autoCloseBrackets: true, + matchBrackets: true, + lint: true, + readonly: false, + autoFocus: true + }; + + expression!: string; + + initDialog = false; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + } + + ngOnInit() { + this.expression = this.data.expression; + this.codeMirrorOptions.readOnly = this.data.readonly; + } + + ngAfterContentInit() { + setTimeout(() => { + this.initDialog = true; + }, 100); + + } + + onSave(): void { + this.dialogRef.close({ + expression: this.expression + }); + } + +} diff --git a/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.css b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.css new file mode 100644 index 0000000000..8ccc4bfdb7 --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.css @@ -0,0 +1,142 @@ +.mat-button-base:not([started]) { + background-color: rgba(0, 0, 0, .12); +} + +form { + display: flex; + flex-direction: column; + width: 500px; + overflow: visible; + padding-bottom: 25px; +} + +.dialog-content { + position: relative; + height: 350px; + opacity: 0; +} + +.dialog-content[started="true"] { + height: auto; + opacity: 1; +} + +.c-config { + position: absolute; + top: 120px; + z-index: 1; + left: 24px; + right: 24px; +} + +.c1 { + display: grid; + grid-template-columns: 250px 100px 150px; +} + +.f1 { + height: 50px; + border: 1px solid #dfdfdf; + border-radius: 4px; + margin-bottom: 10px; + position: relative; + margin-top: 10px; + box-sizing: border-box; +} + + +.f1 mat-label { + position: absolute; + background: #fff; + font-size: 11px; + color: rgb(0 0 0 / 60%); + line-height: 11px; + top: -4px; + left: 4px; + padding: 0 5px; +} + +.delimiter { + padding: 20px 20px; + width: 100%; + height: 40px; + box-sizing: border-box; + position: relative; +} + +.delimiter::after { + content: ''; + position: absolute; + height: 2px; + top: 20px; + left: 0px; + right: 0px; + border-top: 1px solid #c8c8c8; +} + +.toggle-control { + display: block; + position: relative; + padding-left: 40px; + margin-bottom: 12px; + cursor: pointer; + font-size: 22px; + user-select: none; +} + +.toggle-control input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +.toggle-control input:checked~.control { + background-color: var(--button-primary-color);; +} + +.toggle-control .control { + position: absolute; + top: 0; + left: 0; + height: 25px; + width: 25px; + color: #fff; + font-size: 12px; + border-radius: 50%; + background-color: darkgray; + transition: background-color .15s ease-in; + box-sizing: border-box; + align-items: center; + align-content: center; + justify-content: center; + justify-items: center; + display: flex; +} + +mat-expansion-panel { + box-shadow: none !important; + box-sizing: border-box !important; +} + +mat-expansion-panel mat-form-field { + width: 100%; +} + +mat-expansion-panel-header { + font-size: 14px; + opacity: 0.9; + padding: 0 20px 0 8px; +} + +mat-accordion ::ng-deep .mat-expansion-panel-body { + padding: 0px 10px 16px; +} + +mat-accordion { + margin-bottom: 10px; + position: relative; + left: -6px; + width: 516px; +} \ No newline at end of file diff --git a/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.html b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.html new file mode 100644 index 0000000000..83a7811078 --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.html @@ -0,0 +1,149 @@ +

Custom Period

+
+
+
+
+ Start Date: + +
+
+ Interval: + +
+
+ Period: + + Month + Week + Day + Hour + Minute + +
+
+ +
+ +
+
+ + + +
+ {{timeString}} +
+ +
+ + + + + + Cron Mask (advanced) + + + + * Mask: minute hour day(month) month day(week) + + + + + +
+ + +
+
+ +
+
+ + + + + + + +
+ +
+ + + + + + +
+
+ + + + + + +
+ +
+
+
\ No newline at end of file diff --git a/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.ts b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.ts new file mode 100644 index 0000000000..e5d614fb19 --- /dev/null +++ b/frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.ts @@ -0,0 +1,196 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { FormBuilder, Validators } from '@angular/forms'; +import * as moment from 'moment'; +import cronstrue from 'cronstrue'; + +/** + * Dialog for creating policy. + */ +@Component({ + selector: 'cron-config-dialog', + templateUrl: './cron-config-dialog.component.html', + styleUrls: ['./cron-config-dialog.component.css'] +}) +export class CronConfigDialog { + started = false; + period: string; + startDate: string; + + dataForm = this.fb.group({ + mask: ['* * * * *', Validators.required], + interval: [1, Validators.required], + }); + + weekDay = { + Mo: false, + Tu: false, + We: false, + Th: false, + Fr: false, + Sa: false, + Su: false, + } + month = { + January: false, + February: false, + March: false, + April: false, + May: false, + June: false, + July: false, + August: false, + September: false, + October: false, + November: false, + December: false + } + sd: moment.Moment; + timeString!: string; + sd_local: moment.Moment; + + constructor( + public dialogRef: MatDialogRef, + private fb: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any) { + this.period = 'week'; + this.startDate = data.startDate || (new Date).toISOString(); + this.sd = moment(this.startDate).utc(); + this.sd_local = this.sd.clone().local(); + switch (this.sd.day()) { + case 0: this.weekDay.Su = true; break; + case 1: this.weekDay.Mo = true; break; + case 2: this.weekDay.Tu = true; break; + case 3: this.weekDay.We = true; break; + case 4: this.weekDay.Th = true; break; + case 5: this.weekDay.Fr = true; break; + case 6: this.weekDay.Sa = true; break; + } + this.onWeekChange(); + } + + ngOnInit() { + setTimeout(() => { + this.started = true; + }, 200); + } + + onNoClick(): void { + this.dialogRef.close(null); + } + + onSubmit() { + if (this.dataForm.valid) { + const data = this.dataForm.value; + this.dialogRef.close(data); + } + } + + getWeekMap() { + const l = []; + if (this.weekDay.Mo) l.push(1); + if (this.weekDay.Tu) l.push(2); + if (this.weekDay.We) l.push(3); + if (this.weekDay.Th) l.push(4); + if (this.weekDay.Fr) l.push(5); + if (this.weekDay.Sa) l.push(6); + if (this.weekDay.Su) l.push(0); + if (l.length == 7) return '*'; + if (l.length == 0) return '*'; + return l.join(','); + } + + getMonthMap() { + const l = []; + if (this.month.January) l.push(1); + if (this.month.February) l.push(2); + if (this.month.March) l.push(3); + if (this.month.April) l.push(4); + if (this.month.May) l.push(5); + if (this.month.June) l.push(6); + if (this.month.July) l.push(7); + if (this.month.August) l.push(8); + if (this.month.September) l.push(9); + if (this.month.October) l.push(10); + if (this.month.November) l.push(11); + if (this.month.December) l.push(12); + if (l.length == 12) return '*'; + if (l.length == 0) return '*'; + return l.join(','); + } + + getMask() { + switch (this.period) { + case "month": { + return `${this.sd.minute()} ${this.sd.hour()} ${this.sd.date()} ${this.getMonthMap()} *`; + } + case "week": { + return `${this.sd.minute()} ${this.sd.hour()} * * ${this.getWeekMap()}`; + } + case "year": { + return `${this.sd.minute()} ${this.sd.hour()} ${this.sd.date()} ${this.sd.month() + 1} *`; + } + case "day": { + return `${this.sd.minute()} ${this.sd.hour()} * * *`; + } + case "hour": { + return `${this.sd.minute()} * * * *`; + } + case "minute": { + return `* * * * *`; + } + default: + return `* * * * *`; + } + } + + getMaskByInterval() { + const data = this.dataForm.value; + switch (this.period) { + case "month": { + return `${this.sd_local.minute()} ${this.sd_local.hour()} ${this.sd_local.date()} ${this.getMonthMap()}/${data.interval} *`; + } + case "week": { + return `${this.sd_local.minute()} ${this.sd_local.hour()} * * ${this.getWeekMap()}`; + } + case "year": { + return `${this.sd_local.minute()} ${this.sd_local.hour()} ${this.sd_local.date()} ${this.sd_local.month() + 1} *`; + } + case "day": { + return `${this.sd_local.minute()} ${this.sd_local.hour()} */${data.interval} * *`; + } + case "hour": { + return `${this.sd_local.minute()} */${data.interval} * * *`; + } + case "minute": { + return `*/${data.interval} * * * *`; + } + default: + return `* * * * *`; + } + } + + selectPeriod() { + this.setMask(this.getMask()); + this.setText(this.getMaskByInterval()); + } + + onWeekChange() { + this.setMask(this.getMask()); + this.setText(this.getMaskByInterval()); + } + + onMonthChange() { + this.setMask(this.getMask()); + this.setText(this.getMaskByInterval()); + } + + setMask(mask: string) { + const data = this.dataForm.value; + this.dataForm.setValue({ mask: mask, interval: data.interval }); + } + + setText(mask: string) { + this.timeString = cronstrue.toString(mask, { use24HourTimeFormat: true }); + } +} diff --git a/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.css b/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.css index f25bd58240..79f76eaddd 100644 --- a/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.css +++ b/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.css @@ -110,7 +110,7 @@ form { position: absolute; left: 0; right: 0; - top: 30px; + top: 0; bottom: 0; background: #fff; z-index: 1; diff --git a/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.html b/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.html index c8c3b1e925..35f9645f78 100644 --- a/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.html +++ b/frontend/src/app/policy-engine/helpers/import-policy-dialog/import-policy-dialog.component.html @@ -1,21 +1,26 @@
- -

- Enter hedera message timestamp -

-
-
- - Message timestamp - - -
- - -
-
-
+ + + + + +

+ Enter hedera message timestamp +

+
+
+ + Message timestamp + + +
+ + +
+
+
+
@@ -23,7 +28,7 @@

- -
-
- {{getIcon(node)}} -
- {{getName(node)}} -
- delete -
+
+
+
+ unfold_more +
+
+ unfold_less +
- - - -
-
- {{getIcon(node)}} -
- {{getName(node)}} -
- delete -
+ + + + + + + + + + + + + +
+ + +
+
+ {{node.icon}} +
+ + {{node.node.tag}} + +
+ delete +
+
+ arrow_downward +
+
+ arrow_downward + arrow_downward +
+
+ +
+
+ +
+
-
- \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/app/policy-engine/helpers/tree-flat-overview/tree-flat-overview.ts b/frontend/src/app/policy-engine/helpers/tree-flat-overview/tree-flat-overview.ts index af575fad59..ecc37c06c0 100644 --- a/frontend/src/app/policy-engine/helpers/tree-flat-overview/tree-flat-overview.ts +++ b/frontend/src/app/policy-engine/helpers/tree-flat-overview/tree-flat-overview.ts @@ -9,265 +9,310 @@ import { RegisteredBlocks } from '../../registered-blocks'; /** Flat node with expandable and level information */ export class FlatBlockNode { - constructor( - public expandable: boolean, - public level: number, - public node: BlockNode - ) { } + public about!: any; + public prev!: any; + public next!: any; + public root!: any; + public icon!: any; + + constructor( + public expandable: boolean, + public level: number, + public node: BlockNode + ) { + } } /** * @title Tree with flat nodes */ @Component({ - selector: 'tree-flat-overview', - templateUrl: 'tree-flat-overview.html', - styleUrls: ['tree-flat-overview.css'] + selector: 'tree-flat-overview', + templateUrl: 'tree-flat-overview.html', + styleUrls: ['tree-flat-overview.css'] }) export class TreeFlatOverview { - @Input('blocks') blocks!: BlockNode[]; - @Input('errors') errors!: any; - - @Output('delete') delete = new EventEmitter(); - @Output('select') select = new EventEmitter(); - @Output('reorder') reorder = new EventEmitter(); - - currentBlock!: BlockNode; - root!: BlockNode; - - treeControl: FlatTreeControl; - treeFlattener: MatTreeFlattener; - dataSource: MatTreeFlatDataSource; - // expansion model tracks expansion state - expansionModel = new SelectionModel(true); - dragging = false; - expandTimeout: any; - expandDelay = 1000; - validateDrop = false; - - constructor(private registeredBlocks: RegisteredBlocks) { - this.treeFlattener = new MatTreeFlattener(this.transformer, this._getLevel, - this._isExpandable, this._getChildren); - this.treeControl = new FlatTreeControl(this._getLevel, this._isExpandable); - this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); - } - - ngOnChanges(changes: SimpleChanges) { - this.rebuildTreeForData(this.blocks); - if (changes.errors && this.errors) { - this.setErrors(this.errors); + @Input('blocks') blocks!: BlockNode[]; + @Input('errors') errors!: any; + + @Output('delete') delete = new EventEmitter(); + @Output('select') select = new EventEmitter(); + @Output('reorder') reorder = new EventEmitter(); + + currentBlock!: BlockNode; + root!: BlockNode; + + treeControl: FlatTreeControl; + treeFlattener: MatTreeFlattener; + dataSource: MatTreeFlatDataSource; + // expansion model tracks expansion state + expansionModel = new SelectionModel(true); + dragging = false; + expandTimeout: any; + expandDelay = 1000; + validateDrop = false; + isCollapseAll = true; + + constructor(private registeredBlocks: RegisteredBlocks) { + this.treeFlattener = new MatTreeFlattener(this.transformer, this._getLevel, + this._isExpandable, this._getChildren); + this.treeControl = new FlatTreeControl(this._getLevel, this._isExpandable); + this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + this.treeControl.expansionModel.changed.subscribe(e => { + this.isCollapseAll = !e.source.selected.length; + }) + } + + ngOnChanges(changes: SimpleChanges) { + this.rebuildTreeForData(this.blocks); + if (changes.errors && this.errors) { + this.setErrors(this.errors); + } } - } - - transformer = (node: BlockNode, level: number) => { - return new FlatBlockNode(!!(node.children && node.children.length), level, node); - } - private _getLevel = (node: FlatBlockNode) => node.level; - private _isExpandable = (node: FlatBlockNode) => node.expandable; - private _getChildren = (node: BlockNode): Observable => observableOf(node.children); - hasChild = (_: number, _nodeData: FlatBlockNode) => _nodeData.expandable; - - /** - * This constructs an array of nodes that matches the DOM - */ - visibleNodes(): BlockNode[] { - const result: any = []; - - function addExpandedChildren(node: BlockNode, expanded: string[]) { - result.push(node); - if (expanded.includes(node.id)) { - node.children.map((child) => addExpandedChildren(child, expanded)); - } + + transformer = (node: BlockNode, level: number) => { + const e = new FlatBlockNode(!!(node.children && node.children.length), level, node); + e.root = e.node == this.root; + e.icon = this.registeredBlocks.getIcon(e.node.blockType); + e.about = this.registeredBlocks.bindAbout(e.node.blockType, e.node); + return e; } - this.dataSource.data.forEach((node) => { - addExpandedChildren(node, this.expansionModel.selected); - }); - return result; - } - - compare(a: BlockNode, b: BlockNode): boolean { - return a.id == b.id; - } - - /** - * Handle the drop - here we rearrange the data based on the drop event, - * then rebuild the tree. - * */ - drop(event: CdkDragDrop) { - // ignore drops outside of the tree - if (!event.isPointerOverContainer) return; - - // construct a list of visible nodes, this will match the DOM. - // the cdkDragDrop event.currentIndex jives with visible nodes. - // it calls rememberExpandedTreeNodes to persist expand state - const visibleNodes = this.visibleNodes(); - - // deep clone the data source so we can mutate it - const changedData: BlockNode[] = JSON.parse(JSON.stringify(this.dataSource.data)); - - // recursive find function to find siblings of node - function findNodeSiblings(arr: Array, block: BlockNode, compare: any): Array { - let result: any, subResult; - arr.forEach((item, i) => { - if (compare(item, block)) { - result = arr; - } else if (item.children) { - subResult = findNodeSiblings(item.children, block, compare); - if (subResult) { - result = subResult; - } + private _getLevel = (node: FlatBlockNode) => node.level; + private _isExpandable = (node: FlatBlockNode) => node.expandable; + private _getChildren = (node: BlockNode): Observable => observableOf(node.children); + hasChild = (_: number, _nodeData: FlatBlockNode) => _nodeData.expandable; + + /** + * This constructs an array of nodes that matches the DOM + */ + visibleNodes(): BlockNode[] { + const result: any = []; + + function addExpandedChildren(node: BlockNode, expanded: FlatBlockNode[]) { + result.push(node); + if (expanded.find((e) => { return e && e.node.id == node.id })) { + node.children.map((child) => addExpandedChildren(child, expanded)); + } } - }); - return result; + this.dataSource.data.forEach((node) => { + addExpandedChildren(node, this.treeControl.expansionModel.selected); + }); + return result; } - // determine where to insert the node - const nodeAtDest = visibleNodes[event.currentIndex]; - const newSiblings = findNodeSiblings(changedData, nodeAtDest, this.compare); - if (!newSiblings) return; - const insertIndex = newSiblings.findIndex(s => this.compare(s, nodeAtDest)); - - // remove the node from its old place - const node = event.item.data as FlatBlockNode; - const siblings = findNodeSiblings(changedData, node.node, this.compare); - const siblingIndex = siblings.findIndex(n => this.compare(n, node.node)); - const nodeToInsert: BlockNode = siblings.splice(siblingIndex, 1)[0]; - if (nodeAtDest === nodeToInsert) return; - - // ensure validity of drop - must be same level - const nodeAtDestFlatNode: any = this.treeControl.dataNodes.find((n) => this.compare(nodeAtDest, n.node)); - if (this.validateDrop && nodeAtDestFlatNode.level !== node.level) { - alert('Items can only be moved within the same level.'); - return; + compare(a: BlockNode, b: BlockNode): boolean { + return a.id == b.id; } - // insert node - newSiblings.splice(insertIndex, 0, nodeToInsert); + /** + * Handle the drop - here we rearrange the data based on the drop event, + * then rebuild the tree. + * */ + drop(event: CdkDragDrop) { + // ignore drops outside of the tree + if (!event.isPointerOverContainer) return; + + // construct a list of visible nodes, this will match the DOM. + // the cdkDragDrop event.currentIndex jives with visible nodes. + // it calls rememberExpandedTreeNodes to persist expand state + const visibleNodes = this.visibleNodes(); + + // deep clone the data source so we can mutate it + const changedData: BlockNode[] = JSON.parse(JSON.stringify(this.dataSource.data)); + + // recursive find function to find siblings of node + function findNodeSiblings(arr: Array, block: BlockNode, compare: any): Array { + let result: any, subResult; + arr.forEach((item, i) => { + if (compare(item, block)) { + result = arr; + } else if (item.children) { + subResult = findNodeSiblings(item.children, block, compare); + if (subResult) { + result = subResult; + } + } + }); + return result; + } - // rebuild tree with mutated data - // this.rebuildTreeForData(changedData); - this.reorder.emit(changedData); - } + // determine where to insert the node + const nodeAtDest = visibleNodes[event.currentIndex]; + const newSiblings = findNodeSiblings(changedData, nodeAtDest, this.compare); + if (!newSiblings) return; + const insertIndex = newSiblings.findIndex(s => this.compare(s, nodeAtDest)); + + // remove the node from its old place + const node = event.item.data as FlatBlockNode; + const siblings = findNodeSiblings(changedData, node.node, this.compare); + const siblingIndex = siblings.findIndex(n => this.compare(n, node.node)); + const nodeToInsert: BlockNode = siblings.splice(siblingIndex, 1)[0]; + if (nodeAtDest === nodeToInsert) return; + + // ensure validity of drop - must be same level + const nodeAtDestFlatNode: any = this.treeControl.dataNodes.find((n) => this.compare(nodeAtDest, n.node)); + if (this.validateDrop && nodeAtDestFlatNode.level !== node.level) { + alert('Items can only be moved within the same level.'); + return; + } + + // insert node + newSiblings.splice(insertIndex, 0, nodeToInsert); - setErrors(errors: any) { - const keys = Object.keys(errors); - for (let i = 0; i < keys.length; i++) { - const id = keys[i]; - const node: any = this.treeControl.dataNodes.find((n) => n.node.id === id); - this.expand(node); + // rebuild tree with mutated data + // this.rebuildTreeForData(changedData); + this.reorder.emit(changedData); } - } - expand(node: FlatBlockNode) { - const parent = this.getParent(node); - if (parent) { - this.treeControl.expand(parent); - this.expand(parent); + setErrors(errors: any) { + const keys = Object.keys(errors); + for (let i = 0; i < keys.length; i++) { + const id = keys[i]; + const node: any = this.treeControl.dataNodes.find((n) => n.node.id === id); + this.expand(node); + } } - } - - /** - * Iterate over each node in reverse order and return the first node that has a lower level than the passed node. - */ - getParent(node: FlatBlockNode): FlatBlockNode | null { - if (!node) { - return null; + + expand(node: FlatBlockNode) { + const parent = this.getParent(node); + if (parent) { + this.treeControl.expand(parent); + this.expand(parent); + } } - const { treeControl } = this; - const currentLevel = treeControl.getLevel(node); + /** + * Iterate over each node in reverse order and return the first node that has a lower level than the passed node. + */ + getParent(node: FlatBlockNode): FlatBlockNode | null { + if (!node) { + return null; + } + + const { treeControl } = this; + const currentLevel = treeControl.getLevel(node); + + if (currentLevel < 1) { + return null; + } + + const startIndex = treeControl.dataNodes.indexOf(node) - 1; + + for (let i = startIndex; i >= 0; i--) { + const currentNode = treeControl.dataNodes[i]; - if (currentLevel < 1) { - return null; + if (treeControl.getLevel(currentNode) < currentLevel) { + return currentNode; + } + } + + return null; } - const startIndex = treeControl.dataNodes.indexOf(node) - 1; + /** + * Experimental - opening tree nodes as you drag over them + */ + dragStart() { + this.dragging = true; + } - for (let i = startIndex; i >= 0; i--) { - const currentNode = treeControl.dataNodes[i]; + dragEnd() { + this.dragging = false; + } - if (treeControl.getLevel(currentNode) < currentLevel) { - return currentNode; - } + dragHover(node: FlatBlockNode) { + if (this.dragging) { + clearTimeout(this.expandTimeout); + this.expandTimeout = setTimeout(() => { + this.treeControl.expand(node); + }, this.expandDelay); + } } - return null; - } - - /** - * Experimental - opening tree nodes as you drag over them - */ - dragStart() { - this.dragging = true; - } - - dragEnd() { - this.dragging = false; - } - - dragHover(node: FlatBlockNode) { - if (this.dragging) { - clearTimeout(this.expandTimeout); - this.expandTimeout = setTimeout(() => { - this.treeControl.expand(node); - }, this.expandDelay); + dragHoverEnd() { + if (this.dragging) { + clearTimeout(this.expandTimeout); + } + } + + /** + * The following methods are for persisting the tree expand state + * after being rebuilt + */ + + rebuildTreeForData(data: BlockNode[]) { + this.blocks = data; + this.root = data[0]; + this.currentBlock = this.root; + this.dataSource.data = data; + + for (let index = 0; index < this.treeControl.dataNodes.length; index++) { + const p = this.treeControl.dataNodes[index - 1]; + const e = this.treeControl.dataNodes[index]; + const n = this.treeControl.dataNodes[index + 1]; + if (p && e.level == p.level) { + e.about.prev = p.about; + } else { + e.about.prev = null; + } + e.about.next = !!(n && e.level == n.level); + } + + this.treeControl.expansionModel.clear(); + this.expansionModel.selected.forEach((id) => { + const node: any = this.treeControl.dataNodes.find((n) => n.node.id === id); + this.treeControl.expand(node); + }); + } + + getName(node: FlatBlockNode) { + return node.node.tag; + } + + getIcon(node: FlatBlockNode) { + return this.registeredBlocks.getIcon(node.node.blockType); + } + + getAbout(node: FlatBlockNode) { + return this.registeredBlocks.getAbout(node.node.blockType, node.node); } - } - dragHoverEnd() { - if (this.dragging) { - clearTimeout(this.expandTimeout); + onSelect(event: MouseEvent, node: FlatBlockNode) { + event.preventDefault(); + event.stopPropagation(); + this.currentBlock = node.node; + this.select.emit(this.currentBlock); + return false; } - } - - /** - * The following methods are for persisting the tree expand state - * after being rebuilt - */ - - rebuildTreeForData(data: BlockNode[]) { - this.blocks = data; - this.root = data[0]; - this.currentBlock = this.root; - this.dataSource.data = data; - this.expansionModel.selected.forEach((id) => { - const node: any = this.treeControl.dataNodes.find((n) => n.node.id === id); - this.treeControl.expand(node); - }); - } - - getName(node: FlatBlockNode) { - return node.node.tag; - } - - getIcon(node: FlatBlockNode) { - const blockType = node.node.blockType; - return this.registeredBlocks.getIcon(blockType); - } - - onSelect(event: MouseEvent, node: FlatBlockNode) { - event.preventDefault(); - event.stopPropagation(); - this.currentBlock = node.node; - this.select.emit(this.currentBlock); - return false; - } - - onDelete(event: MouseEvent, block: FlatBlockNode) { - event.preventDefault(); - event.stopPropagation(); - this.delete.emit(block.node); - return false; - } - - isSelect(node: FlatBlockNode) { - return this.currentBlock == node.node; - } - - isError(node: FlatBlockNode) { - if (this.errors && this.errors[node.node.id]) { - return true; + + onDelete(event: MouseEvent, block: FlatBlockNode) { + event.preventDefault(); + event.stopPropagation(); + this.delete.emit(block.node); + return false; + } + + isSelect(node: FlatBlockNode) { + return this.currentBlock == node.node; + } + + isError(node: FlatBlockNode) { + if (this.errors && this.errors[node.node.id]) { + return true; + } + return false; + } + + expandAll() { + this.isCollapseAll = false; + this.treeControl.expandAll(); + const values = this.treeControl.expansionModel.selected.map((e: FlatBlockNode) => e.node.id); + this.expansionModel.select.apply(this.expansionModel, values); + } + + collapseAll() { + this.isCollapseAll = true; + this.treeControl.collapseAll(); + this.expansionModel.clear(); } - return false; - } } diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/calculate-config/calculate-config.component.html b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/calculate-config/calculate-config.component.html index 5a83c59d06..48f0f5be90 100644 --- a/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/calculate-config/calculate-config.component.html +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/calculate-config/calculate-config.component.html @@ -1,4 +1,14 @@ + + + + + - + diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.css b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.css new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.css @@ -0,0 +1 @@ + diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.html b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.html new file mode 100644 index 0000000000..c32128a608 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.html @@ -0,0 +1,24 @@ + +
Input Documents + + Aggregate + Separate + +
@@ -54,7 +64,7 @@
Description
+ + + + + + + + + + + +
Output Schema + + + {{schema.name}} + ({{schema.version}}) + ({{schema.status}}) + + +
Expression + +
diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.ts b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.ts new file mode 100644 index 0000000000..4308c18ba9 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.ts @@ -0,0 +1,77 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { BlockNode } from '../../../../helpers/tree-data-source/tree-data-source'; +import { MatDialog } from '@angular/material/dialog'; +import { CodeEditorDialogComponent } from '../../../../helpers/code-editor-dialog/code-editor-dialog.component'; +import { Schema, Token, SchemaField } from 'interfaces'; + +@Component({ + selector: 'app-custom-logic-config', + templateUrl: './custom-logic-config.component.html', + styleUrls: [ + './../../../common-properties/common-properties.component.css', + './custom-logic-config.component.css' + ] +}) +export class CustomLogicConfigComponent implements OnInit { + + @Input('target') target!: BlockNode; + @Input('all') all!: BlockNode[]; + @Input('schemes') schemes!: Schema[]; + @Input('tokens') tokens!: Token[]; + @Input('readonly') readonly!: boolean; + @Input('roles') roles!: string[]; + @Input('topics') topics!: any[]; + @Output() onInit = new EventEmitter(); + + block!: BlockNode; + + propHidden: any = { + outputSchemaGroup: false + }; + + constructor( + private dialog: MatDialog + ) { } + + ngOnInit(): void { + this.onInit.emit(this); + this.load(this.target); + } + + load(block: BlockNode) { + this.block = block; + this.block.uiMetaData = this.block.uiMetaData || {} + this.block.expression = this.block.expression || '' + } + + editExpression($event: MouseEvent) { + const dialogRef = this.dialog.open(CodeEditorDialogComponent, { + width: '80%', + panelClass: 'g-dialog', + data: { + expression: this.block.expression, + readonly: this.readonly + }, + autoFocus: true, + disableClose: true + }) + dialogRef.afterClosed().subscribe(result => { + this.block.expression = result.expression; + }) + } + + onSelectOutput() { + this.block.inputFields = []; + const schema = this.schemes.find(e => e.iri == this.block.outputSchema) + if (schema) { + for (let i = 0; i < schema.fields.length; i++) { + const field = schema.fields[i]; + this.block.inputFields.push({ + name: field.name, + title: field.description, + value: field.name + }) + } + } + } +} diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.html b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.html index 316f2d3522..c267d334f6 100644 --- a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.html +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.html @@ -7,25 +7,101 @@ + - - expand_more + + + expand_more + - UI + Options - + - Rule + Aggregate Type - - - - - - Threshold - - + + Period + Cumulative Dimension + + + + + Timer + + + {{item.tag}} + + + + + + Empty Data + + + + + + + + + + + expand_more + + + Expressions + +
+ add + Add Expression +
+ + + + + + + expand_more + + + Expression {{i}} + + {{expression.name}} = {{expression.value}} + + delete + + + + + + Variable Name + + + + + + + Variable Value + + + + + + + + + Condition + + + + +
\ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.ts b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.ts index e3d1efca7e..d2a52f418d 100644 --- a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.ts +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/aggregate-config/aggregate-config.component.ts @@ -1,6 +1,8 @@ import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; import { Schema, Token } from 'interfaces'; import { BlockNode } from '../../../../helpers/tree-data-source/tree-data-source'; +import { MatDialog } from '@angular/material/dialog'; +import { CronConfigDialog } from '../../../../helpers/cron-config-dialog/cron-config-dialog.component'; /** * Settings for block of 'aggregateDocument' type. @@ -25,11 +27,15 @@ export class AggregateConfigComponent implements OnInit { propHidden: any = { main: false, + options:false, + expressionsGroup: false, + expressions: {}, }; block!: BlockNode; + allTimer!: BlockNode[]; - constructor() { + constructor(private dialog: MatDialog) { } ngOnInit(): void { @@ -42,11 +48,24 @@ export class AggregateConfigComponent implements OnInit { } load(block: BlockNode) { + this.allTimer = this.all?.filter(e=>e.blockType=='timerBlock'); this.block = block; + this.block.expressions = this.block.expressions || []; this.block.uiMetaData = this.block.uiMetaData || {} } onHide(item: any, prop: any) { item[prop] = !item[prop]; } + + addExpression() { + this.block.expressions.push({ + name: '', + value: '', + }) + } + + onRemoveExpression(i: number) { + this.block.expressions.splice(i, 1); + } } diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.css b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.html b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.html new file mode 100644 index 0000000000..1d08868aef --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.html @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Stop Propagation + +
+ + expand_more + + Options
Start Date + +
End Date + +
Period + + Yearly + Monthly + Weekly + Daily + Hourly + Custom + +
Mask + {{block.periodMask}} +
Interval + {{block.periodInterval}} +
\ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.ts b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.ts new file mode 100644 index 0000000000..f3d1928965 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.ts @@ -0,0 +1,81 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Schema, Token } from 'interfaces'; +import { BlockNode } from '../../../../helpers/tree-data-source/tree-data-source'; +import { MatDialog } from '@angular/material/dialog'; +import { CronConfigDialog } from '../../../../helpers/cron-config-dialog/cron-config-dialog.component'; + +/** + * Settings for block of 'timer' type. + */ +@Component({ + selector: 'timer-config', + templateUrl: './timer-config.component.html', + styleUrls: [ + './../../../common-properties/common-properties.component.css', + './timer-config.component.css' + ] +}) +export class TimerConfigComponent implements OnInit { + @Input('target') target!: BlockNode; + @Input('all') all!: BlockNode[]; + @Input('schemes') schemes!: Schema[]; + @Input('tokens') tokens!: Token[]; + @Input('readonly') readonly!: boolean; + @Input('roles') roles!: string[]; + @Input('topics') topics!: any[]; + @Output() onInit = new EventEmitter(); + + propHidden: any = { + main: false, + options:false, + expressionsGroup: false, + expressions: {}, + }; + + block!: BlockNode; + + constructor(private dialog: MatDialog) { + } + + ngOnInit(): void { + this.onInit.emit(this); + this.load(this.target); + } + + ngOnChanges(changes: SimpleChanges) { + this.load(this.target); + } + + load(block: BlockNode) { + this.block = block; + } + + onHide(item: any, prop: any) { + item[prop] = !item[prop]; + } + + selectPeriod() { + if (this.block.period == 'custom') { + const dialogRef = this.dialog.open(CronConfigDialog, { + width: '550px', + disableClose: true, + data: { + startDate: this.block.startDate + }, + autoFocus: false + }); + dialogRef.afterClosed().subscribe(async (result) => { + if (result) { + this.block.periodMask = result.mask; + this.block.periodInterval = result.interval; + } else { + this.block.periodMask = ''; + this.block.periodInterval = ''; + } + }); + } else { + this.block.periodMask = ''; + this.block.periodInterval = ''; + } + } +} diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.css b/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.html b/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.html new file mode 100644 index 0000000000..d2eddbbac3 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + expand_more + + Options
Execution Flow + + First True + All True + +
+ + expand_more + + Conditions +
+ add + Add Condition +
+
+ + expand_more + + Condition {{i}} + If ({{condition.value}}) + If Not({{condition.value}}) + Unconditional + + delete + +
Condition Type + + Equal + Not Equal + Unconditional + +
Condition + +
Actor + + Current User + Document Owner + Document Issuer + +
+ + add_link + + Target Block + + + {{item.tag}} + +
\ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.ts b/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.ts new file mode 100644 index 0000000000..288a6f52d1 --- /dev/null +++ b/frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.ts @@ -0,0 +1,68 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Schema, Token } from 'interfaces'; +import { BlockNode } from '../../../../helpers/tree-data-source/tree-data-source'; + +/** + * Settings for block of 'switch' and 'interfaceStepBlock' types. + */ +@Component({ + selector: 'switch-config', + templateUrl: './switch-config.component.html', + styleUrls: [ + './../../../common-properties/common-properties.component.css', + './switch-config.component.css' + ] +}) +export class SwitchConfigComponent implements OnInit { + @Input('target') target!: BlockNode; + @Input('all') all!: BlockNode[]; + @Input('schemes') schemes!: Schema[]; + @Input('tokens') tokens!: Token[]; + @Input('readonly') readonly!: boolean; + @Input('roles') roles!: string[]; + @Input('topics') topics!: any[]; + @Output() onInit = new EventEmitter(); + + propHidden: any = { + main: false, + options:false, + conditionsGroup: false, + conditions: {}, + }; + + block!: BlockNode; + + constructor() { + } + + ngOnInit(): void { + this.onInit.emit(this); + this.load(this.target); + } + + ngOnChanges(changes: SimpleChanges) { + this.load(this.target); + } + + load(block: BlockNode) { + this.block = block; + this.block.executionFlow = this.block.executionFlow || 'firstTrue'; + this.block.conditions = this.block.conditions || []; + } + + onHide(item: any, prop: any) { + item[prop] = !item[prop]; + } + + addCondition() { + this.block.conditions.push({ + type: 'equal', + value: '', + actor: '', + }) + } + + onRemoveCondition(i: number) { + this.block.conditions.splice(i, 1); + } +} diff --git a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.css b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.css index 336ea948d1..1b39da554f 100644 --- a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.css +++ b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.css @@ -100,7 +100,19 @@ color: black; position: relative; font-weight: 500; + position: relative; +} +.properties .propHeader::after, +.table-body .propHeader::after { + position: absolute; + content: ''; + height: 2px; + border-bottom: 1px solid #b1b1b1; + left: 22px; + right: 0; + bottom: -1px; } + .propBottom { background: #fff; color: black; @@ -347,4 +359,4 @@ input[readonly][type="checkbox"] { top: -2px; left: -4px; position: relative; -} \ No newline at end of file +} diff --git a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.html b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.html index c6637fc6e9..e8169dc5f9 100644 --- a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.html +++ b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.html @@ -10,24 +10,79 @@
- - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -77,8 +132,8 @@ @@ -107,4 +162,4 @@ - + \ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.ts b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.ts index 6bd4d2559a..ae34ebab8f 100644 --- a/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.ts +++ b/frontend/src/app/policy-engine/policy-configuration/common-properties/common-properties.component.ts @@ -1,6 +1,6 @@ import { Component, ComponentFactoryResolver, EventEmitter, Input, OnInit, Output, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core'; import { BlockErrorActions, Schema, Token } from 'interfaces'; -import { RegisteredBlocks } from '../../registered-blocks'; +import { IBlockAbout, RegisteredBlocks } from '../../registered-blocks'; import { BlockNode } from '../../helpers/tree-data-source/tree-data-source'; /** @@ -24,10 +24,12 @@ export class CommonPropertiesComponent implements OnInit { @Output() onInit = new EventEmitter(); propHidden: any = { + about: true, metaData: false, }; block!: BlockNode; + about!: IBlockAbout; errorActions = [ { label: 'No action', @@ -87,6 +89,7 @@ export class CommonPropertiesComponent implements OnInit { } this.configContainer.clear(); const factory: any = this.registeredBlocks.getProperties(block.blockType); + this.about = this.registeredBlocks.bindAbout(block.blockType, block); if (factory) { let componentFactory = this.componentFactoryResolver.resolveComponentFactory(factory); let componentRef: any = this.configContainer.createComponent(componentFactory); diff --git a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.css b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.css index 738c138c4f..4ee689ab92 100644 --- a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.css +++ b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.css @@ -26,6 +26,7 @@ .render { position: relative; flex: 1; + min-width: 1400px; } .main { @@ -278,7 +279,6 @@ .btn-new-block { display: flex; overflow: hidden; - min-width: 45px; height: 52px; flex-direction: column; border: 1px solid transparent; @@ -297,6 +297,13 @@ border: 1px solid rgb(220 220 220); } +.btn-group { + min-width: 52px; +} +.btn-new-block { + min-width: 60px; +} + .btn-group:hover, .btn-new-block:hover { background: rgb(63 81 181 / 3%); @@ -570,4 +577,52 @@ input[readonly] { padding: 10px; background: #fff; border-top: 1px solid #c9c9c9; +} + +.block-group-header { + font-size: 12px; + color: #999; + height: 15px; + line-height: 16px; + overflow: hidden; + padding: 0px 8px; + position: relative; +} +.block-group-header span { + position: relative; + z-index: 1; + background: #fff; + padding: 0px 2px 0px 2px; + margin: 0px 2px 0px 2px; +} +.block-group-header::after { + display: block; + position: absolute; + content: ''; + border-top: 1px solid #999; + height: 2px; + top: 8px; + left: 6px; + right: 6px; + z-index: 0; +} + +.copy-blocks-mode:active { + background-color: #d1d1d1; +} + +.copy-blocks-mode:hover { + background-color: #ffffff; +} + +.copy-blocks-mode-active { + background-color: #d1d1d1; +} + +.copy-blocks-mode-active:active { + background-color: #ffffff; +} + +.copy-blocks-mode-active:hover { + background-color: #d1d1d1; } \ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.html b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.html index 9bd875823b..10da7485a1 100644 --- a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.html +++ b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.html @@ -29,8 +29,6 @@
{{errorsCount}}
-
-
public Publish @@ -38,7 +36,32 @@
-
+
+ login + Open +
+ +
+ undo + Undo +
+ +
+ redo + Redo +
+ +
+ content_copy + Copy Blocks +
+ +
+ +
home Main
@@ -46,7 +69,7 @@
-
+
description Verifiable Credential
@@ -54,7 +77,7 @@
-
+
paid Tokens
@@ -62,7 +85,7 @@
-
+
calculate Calculate
@@ -70,7 +93,7 @@
-
+
addchart Report
@@ -78,13 +101,13 @@
-
- -
- login - Open -
+ +
+ {{item.icon}} + {{item.name}} +
+
@@ -104,7 +127,8 @@
- + +
@@ -134,11 +158,13 @@ - + +
-
+
Description
@@ -166,12 +192,14 @@
+ [readonly]="readonly" [tokens]="tokens" [roles]="policy.policyRoles" + [topics]="policy.policyTopics"> + [readonly]="readonly" [tokens]="tokens" [roles]="policy.policyRoles" + [topics]="policy.policyTopics">
@@ -190,41 +218,66 @@
-
- {{item.icon}} - {{item.name}} -
+ +
+ {{item.icon}} + {{item.name}} +
+
+ {{item.name}} +
+
-
- {{item.icon}} - {{item.name}} -
+ +
+ {{item.icon}} + {{item.name}} +
+
+ {{item.name}} +
+
-
- {{item.icon}} - {{item.name}} -
+ +
+ {{item.icon}} + {{item.name}} +
+
+ {{item.name}} +
+
-
- {{item.icon}} - {{item.name}} -
+ +
+ {{item.icon}} + {{item.name}} +
+
+ {{item.name}} +
+
-
- {{item.icon}} - {{item.name}} -
+ +
+ {{item.icon}} + {{item.name}} +
+
+ {{item.name}} +
+
\ No newline at end of file diff --git a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts index c475bef52a..2be076b506 100644 --- a/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts +++ b/frontend/src/app/policy-engine/policy-configuration/policy-configuration/policy-configuration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, HostListener, OnInit } from '@angular/core'; import { BlockNode } from '../../helpers/tree-data-source/tree-data-source'; import { SchemaService } from 'src/app/services/schema.service'; import { Schema, SchemaHelper, SchemaStatus, Token } from 'interfaces'; @@ -7,10 +7,12 @@ import { forkJoin } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { TokenService } from 'src/app/services/token.service'; -import { RegisteredBlocks } from '../../registered-blocks'; +import { BlockGroup, RegisteredBlocks } from '../../registered-blocks'; import { PolicyAction, SavePolicyDialog } from '../../helpers/save-policy-dialog/save-policy-dialog.component'; import { SetVersionDialog } from 'src/app/schema-engine/set-version-dialog/set-version-dialog.component'; import * as yaml from 'js-yaml'; +import { Clipboard } from '@angular/cdk/clipboard'; +import { ConfirmationDialogComponent } from 'src/app/components/confirmation-dialog/confirmation-dialog.component'; /** * The page for editing the policy and blocks. @@ -21,6 +23,37 @@ import * as yaml from 'js-yaml'; styleUrls: ['./policy-configuration.component.css'] }) export class PolicyConfigurationComponent implements OnInit { + @HostListener('document:copy', ['$event']) + copy(event: ClipboardEvent) { + if (this.currentBlock + && this.copyBlocksMode + && this.currentView === 'blocks' + && !this.readonly) { + event.preventDefault(); + navigator.clipboard.writeText(JSON.stringify(this.currentBlock)); + } + } + + @HostListener('document:paste', ['$event']) + paste(evt: ClipboardEvent) { + if (this.currentBlock + && this.copyBlocksMode + && this.currentView === 'blocks' + && !this.readonly) { + evt.preventDefault(); + try { + const parsedBlockData = JSON.parse(evt.clipboardData?.getData('text') || "null"); + this.onCopyBlock(parsedBlockData); + } + catch { + console.warn("Block data is incorrect"); + return; + } + + + } + } + loading: boolean = true; blocks: BlockNode[] = []; @@ -38,13 +71,12 @@ export class PolicyConfigurationComponent implements OnInit { errors: any[] = []; errorsCount: number = -1; errorsMap: any; + private _undoDepth: number = 0; colGroup1 = false; colGroup2 = false; colGroup3 = true; - indexBlock: number = 0; - codeMirrorOptions: any = { theme: 'default', mode: 'application/ld+json', @@ -65,6 +97,16 @@ export class PolicyConfigurationComponent implements OnInit { }; propTab: string = 'Properties'; policyTab: string = 'Description'; + private blockToCopy?: BlockNode; + copyBlocksMode: boolean = false; + groupBlocks: any = { + Main: [], + Documents: [], + Tokens: [], + Calculate: [], + Report: [], + UnGroupedBlocks: [] + } constructor( public registeredBlocks: RegisteredBlocks, @@ -106,6 +148,30 @@ export class PolicyConfigurationComponent implements OnInit { setTimeout(() => { this.loading = false; }, 500); return; } + + if (!this.compareStateAndConfig(this.objectToJson(policy?.config)) && !this.readonly) { + const applyChanesDialog = this.dialog.open(ConfirmationDialogComponent, { + data: { + dialogTitle: "Apply latest changes", + dialogText: "Do you want to apply latest changes?" + }, + disableClose: true + }) + applyChanesDialog.afterClosed().subscribe((result) => { + if (result) { + this.loadState(); + } + else { + this.clearState(); + this.saveState(); + } + }) + + } else { + this.clearState(); + this.saveState(); + } + this.schemaService.getSchemes(policy.topicId).subscribe((data2: any) => { const schemes = data2 || []; this.schemes = SchemaHelper.map(schemes) || []; @@ -135,7 +201,6 @@ export class PolicyConfigurationComponent implements OnInit { this.readonly = policy.status == 'PUBLISH'; this.policy = policy; this.setBlocks(root); - this.indexBlock = this.allBlocks.length + 1; this.errors = []; this.errorsCount = -1; this.errorsMap = {}; @@ -145,7 +210,7 @@ export class PolicyConfigurationComponent implements OnInit { setBlocks(root: BlockNode) { this.root = root; this.blocks = [root]; - this.currentBlock = root; + this.onSelect(this.root); this.allBlocks = this.all(root); this.allBlocks.forEach((b => { if (!b.id) b.id = this.registeredBlocks.generateUUIDv4(); @@ -172,9 +237,89 @@ export class PolicyConfigurationComponent implements OnInit { onSelect(block: BlockNode) { this.currentBlock = block; + const allowedChildren = this.registeredBlocks.allowedChildren[block.blockType]; + const groupBlocks: any = {}; + const unGroupedBlocks: any[] = []; + for (const key in BlockGroup) { + this.groupBlocks[key] = []; + } + + for (let i = 0; i < allowedChildren.length; i++) { + const allowedChild = allowedChildren[i]; + const type = allowedChild.type; + if (!allowedChild.group) { + allowedChild.group = this.registeredBlocks.blocks[allowedChild.type].group; + } + if (!allowedChild.header) { + allowedChild.header = this.registeredBlocks.blocks[allowedChild.type].header; + } + if (!groupBlocks[allowedChild.group]) { + groupBlocks[allowedChild.group] = {}; + } + if (allowedChild.group === BlockGroup.UnGrouped) { + unGroupedBlocks.push({ + type: type, + icon: this.registeredBlocks.getIcon(type), + name: this.registeredBlocks.getName(type), + title: this.registeredBlocks.getTitle(type) + }); + continue; + } + if (!groupBlocks[allowedChild.group][allowedChild.header]) { + groupBlocks[allowedChild.group][allowedChild.header] = []; + } + groupBlocks[allowedChild.group][allowedChild.header].push({ + type: type, + icon: this.registeredBlocks.getIcon(type), + name: this.registeredBlocks.getName(type), + title: this.registeredBlocks.getTitle(type) + }); + } + + const groupBlockKeys = Object.keys(groupBlocks); + for (let i = 0; i < groupBlockKeys.length; i++) { + const groupName = groupBlockKeys[i]; + const groupsWithHeaders = groupBlocks[groupName]; + const groupsWithHeadersKeys = Object.keys(groupsWithHeaders); + for (let j = 0; j < groupsWithHeadersKeys.length; j++) { + const subGroupName = groupsWithHeadersKeys[j]; + const subGroupElements = groupsWithHeaders[groupsWithHeadersKeys[j]]; + this.groupBlocks[groupName].push({ + name: subGroupName + }); + this.groupBlocks[groupName] = this.groupBlocks[groupName].concat(subGroupElements); + } + } + + this.groupBlocks.unGroupedBlocks = unGroupedBlocks; return false; } + prepareChildrenBlockToCopy(blocks: BlockNode[]) { + if (!blocks) { + return; + } + + for (let i = 0; i < blocks.length; i++) { + const block = blocks[i]; + block.id = this.registeredBlocks.generateUUIDv4(); + block.tag = this.getNewTag(); + this.prepareChildrenBlockToCopy(block.children); + } + } + + onCopyBlock(block?: BlockNode) { + if (this.currentBlock && block) { + block.id = this.registeredBlocks.generateUUIDv4(); + block.tag = this.getNewTag(); + this.prepareChildrenBlockToCopy(block.children); + this.currentBlock.children = this.currentBlock.children || []; + this.currentBlock.children.push(block); + this.setBlocks(this.blocks[0]); + this.saveState(); + } + } + onAdd(type: any) { if (this.currentBlock) { this.currentBlock.children = this.currentBlock.children || []; @@ -182,16 +327,33 @@ export class PolicyConfigurationComponent implements OnInit { if (this.currentBlock.permissions) { permissions = this.currentBlock.permissions.slice(); } - const newBlock = this.registeredBlocks.newBlock(type, permissions, this.indexBlock); + const newBlock = this.registeredBlocks.newBlock(type, permissions); + newBlock.tag = this.getNewTag(); this.currentBlock.children.push(newBlock); this.setBlocks(this.blocks[0]); - this.indexBlock++; + this.saveState(); } } + getNewTag(): string { + const nameMap: any = {}; + for (let block of this.allBlocks) { + nameMap[block.tag] = true; + } + let name = 'Block'; + for (let i = 1; i < 1000; i++) { + name = `Block_${i}`; + if (!nameMap[name]) { + return name; + } + } + return 'Block'; + } + onDelete(block: BlockNode) { this.removeBlock(this.blocks, block); this.setBlocks(this.blocks[0]); + this.saveState(); return false; } @@ -211,6 +373,113 @@ export class PolicyConfigurationComponent implements OnInit { onReorder(blocks: BlockNode[]) { this.setBlocks(blocks[0]); + this.saveState(); + } + + compareStateAndConfig(JSONconfig: string) { + const states = localStorage[this.policyId] && JSON.parse(localStorage[this.policyId]); + if (!states) { + return true; + } + + const state = states[states.length - 1] && JSON.parse(states[states.length - 1]); + if (!state) { + return true; + } + if (state.view === 'json' || state.view === 'blocks') { + return state.value === JSONconfig; + } + if (state.view === 'yaml') { + return this.yamlToJson(state.value) === JSONconfig; + } + + return true; + } + + async loadState(states?: any, number?: number) { + let stateValues = states || (localStorage[this.policyId] && JSON.parse(localStorage[this.policyId])); + if (!stateValues) { + return false; + } + + let root: any = {}; + if (typeof number !== 'number') { + root = JSON.parse(stateValues[stateValues.length - 1]); + } else if (number >= 0) { + const stateValue = stateValues[number]; + if (!stateValue) { + return false; + } + + root = JSON.parse(stateValue); + } + + if (!root.view) { + return false; + } + if (this.currentView !== root.view) { + this.currentView = root.view; + await this.onView(root.view); + } + if (root.view === 'yaml' || root.view === 'json') { + this.code = root.value; + } + if (root.view === 'blocks') { + const rootBlock = this.jsonToObject(root.value); + this.setBlocks(rootBlock); + this.errors = []; + this.errorsCount = -1; + this.errorsMap = {}; + } + + return true; + } + + clearState() { + localStorage.removeItem(this.policyId); + } + + saveState() { + if (this.readonly) { + return; + } + + let stateValue = localStorage[this.policyId] && JSON.parse(localStorage[this.policyId]); + if (stateValue && stateValue.length > 5) { + stateValue.shift(); + localStorage.setItem(this.policyId, JSON.stringify(stateValue)); + } + else if (!stateValue) { + stateValue = []; + } + + let state = ""; + if (this.currentView == 'blocks') { + state = JSON.stringify({ + view: this.currentView, + value: this.objectToJson(this.root) + }); + } + if (this.currentView == 'yaml') { + state = JSON.stringify({ + view: this.currentView, + value: this.code + }); + } + if (this.currentView == 'json') { + state = JSON.stringify({ + view: this.currentView, + value: this.code + }); + } + + if (this._undoDepth) { + stateValue.slice(0, stateValue.length - this._undoDepth - 1); + this._undoDepth = 0; + } + + stateValue.push(state); + localStorage.setItem(this.policyId, JSON.stringify(stateValue)); } hasChild(_: number, node: BlockNode) { @@ -231,6 +500,9 @@ export class PolicyConfigurationComponent implements OnInit { this.policy.config = root; this.policyEngineService.update(this.policyId, this.policy).subscribe((policy) => { this.setPolicy(policy); + if (this.compareStateAndConfig(this.objectToJson(root))) { + this.clearState(); + } this.loading = false; }, (e) => { console.error(e.error); @@ -297,7 +569,7 @@ export class PolicyConfigurationComponent implements OnInit { this.errorsMap[element.id] = element.errors; } this.blocks = [this.root]; - this.currentBlock = this.root; + this.onSelect(this.root); this.loading = false; }, (e) => { this.loading = false; @@ -377,7 +649,6 @@ export class PolicyConfigurationComponent implements OnInit { return; } this.setBlocks(root); - this.indexBlock = this.allBlocks.length + 1; } if (type == 'json') { let code = ""; @@ -447,4 +718,26 @@ export class PolicyConfigurationComponent implements OnInit { const root = this.jsonToObject(json); return this.objectToYaml(root); } + + async undoPolicy() { + const stateValues = localStorage[this.policyId] && JSON.parse(localStorage[this.policyId]); + if (!stateValues) { + return; + } + + if (await this.loadState(stateValues, stateValues.length - 2 - this._undoDepth)) { + this._undoDepth++; + } + } + + async redoPolicy() { + const stateValues = localStorage[this.policyId] && JSON.parse(localStorage[this.policyId]); + if (!stateValues) { + return; + } + + if (await this.loadState(stateValues, stateValues.length - this._undoDepth)) { + this._undoDepth--; + } + } } diff --git a/frontend/src/app/policy-engine/policy-engine.module.ts b/frontend/src/app/policy-engine/policy-engine.module.ts index ef898c668b..6bfbc6c5ac 100644 --- a/frontend/src/app/policy-engine/policy-engine.module.ts +++ b/frontend/src/app/policy-engine/policy-engine.module.ts @@ -45,11 +45,14 @@ import { CalculateMathConfigComponent } from './policy-configuration/blocks/calc import { JsonPropertiesComponent } from './policy-configuration/json-properties/json-properties.component'; import { ReportBlockComponent } from './policy-viewer/blocks/report-block/report-block.component'; import { ReportItemConfigComponent } from './policy-configuration/blocks/report/report-item-config/report-item-config.component'; -import { - PaginationAddonBlockComponent -} from './policy-viewer/blocks/pagination-addon-block/pagination-addon-block.component'; -import { Dragonglass } from './helpers/dragonglass/dragonglass.component'; +import { PaginationAddonBlockComponent } from './policy-viewer/blocks/pagination-addon-block/pagination-addon-block.component'; import { ReassigningConfigComponent } from './policy-configuration/blocks/documents/reassigning-config/reassigning-config.component'; +import { CommonComponentsModule } from '../common-components.module'; +import { CronConfigDialog } from './helpers/cron-config-dialog/cron-config-dialog.component'; +import { TimerConfigComponent } from './policy-configuration/blocks/documents/timer-config/timer-config.component'; +import { CustomLogicConfigComponent } from './policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component'; +import { CodeEditorDialogComponent } from './helpers/code-editor-dialog/code-editor-dialog.component'; +import { SwitchConfigComponent } from './policy-configuration/blocks/main/switch-config/switch-config.component'; @NgModule({ declarations: [ @@ -92,12 +95,17 @@ import { ReassigningConfigComponent } from './policy-configuration/blocks/docume JsonPropertiesComponent, ReportBlockComponent, ReportItemConfigComponent, - Dragonglass, - ReassigningConfigComponent + ReassigningConfigComponent, + CronConfigDialog, + TimerConfigComponent, + CustomLogicConfigComponent, + CodeEditorDialogComponent, + SwitchConfigComponent ], imports: [ CommonModule, FormsModule, + CommonComponentsModule, CodemirrorModule, MaterialModule, SchemaEngineModule, @@ -141,12 +149,11 @@ import { ReassigningConfigComponent } from './policy-configuration/blocks/docume CalculateConfigComponent, CalculateMathConfigComponent, JsonPropertiesComponent, - Dragonglass, - ReassigningConfigComponent + ReassigningConfigComponent, + CronConfigDialog ], providers: [ RegisteredBlocks ] }) -export class PolicyEngineModule { -} +export class PolicyEngineModule { } diff --git a/frontend/src/app/policy-engine/registered-blocks.ts b/frontend/src/app/policy-engine/registered-blocks.ts index ff67125b4e..d541a0949b 100644 --- a/frontend/src/app/policy-engine/registered-blocks.ts +++ b/frontend/src/app/policy-engine/registered-blocks.ts @@ -24,10 +24,11 @@ import { CalculateMathConfigComponent } from './policy-configuration/blocks/calc import { BlockNode } from "./helpers/tree-data-source/tree-data-source"; import { ReportBlockComponent } from "./policy-viewer/blocks/report-block/report-block.component"; import { ReportItemConfigComponent } from "./policy-configuration/blocks/report/report-item-config/report-item-config.component"; -import { - PaginationAddonBlockComponent -} from './policy-viewer/blocks/pagination-addon-block/pagination-addon-block.component'; +import { PaginationAddonBlockComponent } from './policy-viewer/blocks/pagination-addon-block/pagination-addon-block.component'; import { ReassigningConfigComponent } from "./policy-configuration/blocks/documents/reassigning-config/reassigning-config.component"; +import { TimerConfigComponent } from "./policy-configuration/blocks/documents/timer-config/timer-config.component"; +import { CustomLogicConfigComponent } from './policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component'; +import { SwitchConfigComponent } from "./policy-configuration/blocks/main/switch-config/switch-config.component"; export enum BlockType { Container = 'interfaceContainerBlock', @@ -50,6 +51,9 @@ export enum BlockType { ReportItem = 'reportItemBlock', ReassigningBlock = 'reassigningBlock', PaginationAddon = 'paginationAddon', + TimerBlock = 'timerBlock', + CustomLogicBlock = 'customLogicBlock', + Switch = 'switchBlock', } export enum BlockGroup { @@ -57,106 +61,830 @@ export enum BlockGroup { Documents = 'Documents', Tokens = 'Tokens', Calculate = 'Calculate', - Report = 'Report' + Report = 'Report', + UnGrouped = 'UnGrouped' +} + +export enum BlockHeaders { + UIComponents = 'UI Components', + ServerBlocks = 'Server Blocks', + Addons = 'Addons' +} + +export interface IBlockAbout { + post: boolean; + get: boolean; + input: InputType; + output: InputType; + children: ChildrenType; + control: ControlType; + prev?: IBlockAbout; + next?: boolean; +} + +type ConfigFunction = ((block: any, prev?: IBlockAbout, next?: boolean) => T) | T; + +export interface IBlockAboutConfig { + post: ConfigFunction; + get: ConfigFunction; + input: ConfigFunction; + output: ConfigFunction; + children: ConfigFunction; + control: ConfigFunction; +} + +export enum InputType { + None = 'None', + Single = 'Single', + Multiple = 'Multiple', + Any = 'Any', +} + +export enum ChildrenType { + None = 'None', + Special = 'Special', + Any = 'Any', +} + +export enum ControlType { + UI = 'UI', + Special = 'Special', + Server = 'Server', + None = 'None', +} + +export class BlockAbout { + private _propFunc: { [x: string]: ConfigFunction } = {}; + private _propVal: { [x: string]: any } = {}; + private _setProp(about: any, name: string) { + if (typeof about[name] == 'function') { + this._propFunc[name] = about[name]; + } else { + this._propVal[name] = about[name]; + this._propFunc[name] = (block: any, prev?: IBlockAbout, next?: boolean) => { + return this._propVal[name]; + }; + } + } + + constructor(about: IBlockAboutConfig) { + this._setProp(about, 'post'); + this._setProp(about, 'get'); + this._setProp(about, 'input'); + this._setProp(about, 'output'); + this._setProp(about, 'children'); + this._setProp(about, 'control'); + } + + public get(block: any): IBlockAbout { + return { + post: this._propFunc.post(block), + get: this._propFunc.get(block), + input: this._propFunc.input(block), + output: this._propFunc.output(block), + children: this._propFunc.children(block), + control: this._propFunc.control(block), + } + } + + public bind(block: any, prev?: IBlockAbout, next?: boolean): IBlockAbout { + const bind = { + _block: block, + _prev: prev, + _next: next, + _post: this._propFunc.post, + _get: this._propFunc.get, + _input: this._propFunc.input, + _output: this._propFunc.output, + _children: this._propFunc.children, + _control: this._propFunc.control, + get post() { + return this._post(this._block, this._prev, this._next); + }, + get get() { + return this._get(this._block, this._prev, this._next); + }, + get input() { + return this._input(this._block, this._prev, this._next); + }, + get output() { + return this._output(this._block, this._prev, this._next); + }, + get children() { + return this._children(this._block, this._prev, this._next); + }, + get control() { + return this._control(this._block, this._prev, this._next); + }, + set prev(value: IBlockAbout) { + this._prev = value; + }, + set next(value: boolean) { + this._next = value; + } + } + return bind + } +} + +export interface IBlockSetting { + type: BlockType; + icon: string; + name: string; + title: string; + group: BlockGroup; + header: BlockHeaders; + factory: any; + property: any; + about: IBlockAboutConfig; + allowedChildren?: ChildrenDisplaySettings[]; +} + +export interface ChildrenDisplaySettings { + type: BlockType, + group?: BlockGroup, + header?: BlockHeaders } @Injectable() export class RegisteredBlocks { - public readonly blocks: BlockType[]; + public readonly blocks: any; public readonly icons: any; public readonly names: any; public readonly titles: any; - public readonly groups: any; public readonly factories: any; public readonly properties: any; + public readonly about: any; + public readonly allowedChildren: any; + + private readonly defaultA = new BlockAbout({ + post: false, + get: false, + input: InputType.None, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.None, + }) constructor() { - this.blocks = []; + this.blocks = {}; this.icons = {}; this.names = {}; this.titles = {}; - this.groups = {}; this.factories = {}; this.properties = {}; + this.about = {}; + this.allowedChildren = {}; + + const allowedChildrenStepContainerBlocks = [ + { + type: BlockType.Information + }, + { + type: BlockType.PolicyRoles + }, + { + type: BlockType.Action + }, + { + type: BlockType.Container + }, + { + type: BlockType.Step + }, + { + type: BlockType.Switch + }, + { + type: BlockType.DocumentsViewer + }, + { + type: BlockType.Request + }, + { + type: BlockType.SendToGuardian + }, + { + type: BlockType.ExternalData + }, + { + type: BlockType.AggregateDocument + }, + { + type: BlockType.ReassigningBlock + }, + { + type: BlockType.TimerBlock + }, + { + type: BlockType.Mint + }, + { + type: BlockType.Wipe + }, + { + type: BlockType.Calculate + }, + { + type: BlockType.CustomLogicBlock + }, + { + type: BlockType.Report + } + ]; + + // Main, UI Components + this.addBlock({ + type: BlockType.Container, + icon: 'tab', + name: 'Container', + title: `Add 'Container' Block`, + group: BlockGroup.Main, + header: BlockHeaders.UIComponents, + factory: ContainerBlockComponent, + property: ContainerConfigComponent, + about: { + post: false, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Any, + control: ControlType.UI, + }, + allowedChildren: allowedChildrenStepContainerBlocks + }); + this.addBlock({ + type: BlockType.Step, + icon: 'vertical_split', + name: 'Step', + title: `Add 'Step' Block`, + group: BlockGroup.Main, + header: BlockHeaders.UIComponents, + factory: StepBlockComponent, + property: ContainerConfigComponent, + about: { + post: false, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Any, + control: ControlType.UI, + }, + allowedChildren: allowedChildrenStepContainerBlocks + }); + this.addBlock({ + type: BlockType.PolicyRoles, + icon: 'manage_accounts', + name: 'Roles', + title: `Add 'Choice Of Roles' Block`, + group: BlockGroup.Main, + header: BlockHeaders.UIComponents, + factory: RolesBlockComponent, + property: RolesConfigComponent, + about: { + post: true, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.UI, + } + }); + this.addBlock({ + type: BlockType.Information, + icon: 'info', + name: 'Information', + title: `Add 'Information' Block`, + group: BlockGroup.Main, + header: BlockHeaders.UIComponents, + factory: InformationBlockComponent, + property: InformationConfigComponent, + about: { + post: false, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.UI, + } + }); + this.addBlock({ + type: BlockType.Action, + icon: 'flash_on', + name: 'Action', + title: `Add 'Action' Block`, + group: BlockGroup.Main, + header: BlockHeaders.UIComponents, + factory: ActionBlockComponent, + property: ActionConfigComponent, + about: { + post: true, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Special, + control: ControlType.UI, + }, + allowedChildren: [ + { + type: BlockType.DocumentsSourceAddon, + group: BlockGroup.UnGrouped + } + ] + }); + + // Main, Server Blocks + this.addBlock({ + type: BlockType.Switch, + icon: 'rule', + name: 'Switch', + title: `Add 'Switch' Block`, + group: BlockGroup.Main, + header: BlockHeaders.ServerBlocks, + factory: null, + property: SwitchConfigComponent, + about: { + post: false, + get: false, + input: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + + // Documents, UI Components + this.addBlock({ + type: BlockType.DocumentsViewer, + icon: 'table_view', + name: 'Documents', + title: `Add 'Documents Source' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.UIComponents, + factory: DocumentsSourceBlockComponent, + property: DocumentSourceComponent, + about: { + post: false, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Special, + control: ControlType.UI, + }, + allowedChildren: [ + { + type: BlockType.DocumentsSourceAddon, + group: BlockGroup.UnGrouped + }, + { + type: BlockType.PaginationAddon, + group: BlockGroup.UnGrouped + } + ] + }); + this.addBlock({ + type: BlockType.Request, + icon: 'dynamic_form', + name: 'Request', + title: `Add 'Request' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.UIComponents, + factory: RequestDocumentBlockComponent, + property: RequestConfigComponent, + about: { + post: true, + get: true, + input: InputType.None, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + return InputType.Single; + }, + children: ChildrenType.Special, + control: ControlType.UI, + }, + allowedChildren: [ + { + type: BlockType.DocumentsSourceAddon, + group: BlockGroup.UnGrouped + } + ] + }); - this.register(BlockType.Container, 'tab', 'Container', `Add 'Container' Block`); - this.register(BlockType.Step, 'vertical_split', 'Step', `Add 'Step' Block`); - this.register(BlockType.PolicyRoles, 'manage_accounts', 'Roles', `Add 'Choice Of Roles' Block`); - this.register(BlockType.Information, 'info', 'Information', `Add 'Information' Block`); - this.register(BlockType.Action, 'flash_on', 'Action', `Add 'Action' Block`); - this.register(BlockType.DocumentsViewer, 'table_view', 'Documents', `Add 'Documents Source' Block`); - this.register(BlockType.Request, 'dynamic_form', 'Request', `Add 'Request' Block`); - this.register(BlockType.SendToGuardian, 'send', 'Send', `Add 'Send' Block`); - this.register(BlockType.ExternalData, 'cloud', 'External Data', `Add 'External Data' Block`); - this.register(BlockType.AggregateDocument, 'merge_type', 'Aggregate Data', `Add 'Aggregate' Block`); - this.register(BlockType.FiltersAddon, 'filter_alt', 'Filters Addon', `Add 'Filters' Block`); - this.register(BlockType.Mint, 'paid', 'Mint', `Add 'Mint' Block`); - this.register(BlockType.Wipe, 'delete', 'Wipe', `Add 'Wipe' Block`); - this.register(BlockType.DocumentsSourceAddon, 'source', 'Source', `Add 'DocumentsSourceAddon' Block`); - this.register(BlockType.Calculate, 'bar_chart', 'Calculate', `Add 'Calculate' Addon`); - this.register(BlockType.CalculateMathAddon, 'calculate', 'Math Addon', `Add 'Math' Addon`); - this.register(BlockType.Report, 'addchart', 'Report', `Add 'Report' Block`); - this.register(BlockType.ReportItem, 'list_alt', 'Report Item', `Add 'Report Item' Block`); - this.register(BlockType.ReassigningBlock, 'content_copy', 'Reassigning', `Add 'Reassigning' Block`); - this.register(BlockType.PaginationAddon, 'filter_alt', 'Pagination', `Add 'Pagination' Addon`); - - this.registerGroup(BlockGroup.Main, BlockType.Container); - this.registerGroup(BlockGroup.Main, BlockType.Step); - this.registerGroup(BlockGroup.Main, BlockType.PolicyRoles); - this.registerGroup(BlockGroup.Main, BlockType.Information); - this.registerGroup(BlockGroup.Main, BlockType.Action); - this.registerGroup(BlockGroup.Documents, BlockType.DocumentsViewer); - this.registerGroup(BlockGroup.Documents, BlockType.Request); - this.registerGroup(BlockGroup.Documents, BlockType.SendToGuardian); - this.registerGroup(BlockGroup.Documents, BlockType.ExternalData); - this.registerGroup(BlockGroup.Documents, BlockType.AggregateDocument); - this.registerGroup(BlockGroup.Documents, BlockType.FiltersAddon); - this.registerGroup(BlockGroup.Documents, BlockType.DocumentsSourceAddon); - this.registerGroup(BlockGroup.Documents, BlockType.ReassigningBlock); - this.registerGroup(BlockGroup.Documents, BlockType.PaginationAddon); - this.registerGroup(BlockGroup.Tokens, BlockType.Mint); - this.registerGroup(BlockGroup.Tokens, BlockType.Wipe); - this.registerGroup(BlockGroup.Calculate, BlockType.Calculate); - this.registerGroup(BlockGroup.Calculate, BlockType.CalculateMathAddon); - this.registerGroup(BlockGroup.Report, BlockType.Report); - this.registerGroup(BlockGroup.Report, BlockType.ReportItem); - - this.registerFactory(BlockType.Container, ContainerBlockComponent); - this.registerFactory(BlockType.DocumentsViewer, DocumentsSourceBlockComponent); - this.registerFactory(BlockType.Request, RequestDocumentBlockComponent); - this.registerFactory(BlockType.Action, ActionBlockComponent); - this.registerFactory(BlockType.Step, StepBlockComponent); - this.registerFactory(BlockType.Information, InformationBlockComponent); - this.registerFactory(BlockType.PolicyRoles, RolesBlockComponent); - this.registerFactory(BlockType.FiltersAddon, FiltersAddonBlockComponent); - this.registerFactory(BlockType.PaginationAddon, PaginationAddonBlockComponent); - this.registerFactory(BlockType.Report, ReportBlockComponent); - - this.registerProperties(BlockType.DocumentsViewer, DocumentSourceComponent); - this.registerProperties(BlockType.Action, ActionConfigComponent); - this.registerProperties(BlockType.Container, ContainerConfigComponent); - this.registerProperties(BlockType.Request, RequestConfigComponent); - this.registerProperties(BlockType.Step, ContainerConfigComponent); - this.registerProperties(BlockType.Mint, MintConfigComponent); - this.registerProperties(BlockType.SendToGuardian, SendConfigComponent); - this.registerProperties(BlockType.ExternalData, ExternalDataConfigComponent); - this.registerProperties(BlockType.AggregateDocument, AggregateConfigComponent); - this.registerProperties(BlockType.Wipe, MintConfigComponent); - this.registerProperties(BlockType.Information, InformationConfigComponent); - this.registerProperties(BlockType.PolicyRoles, RolesConfigComponent); - this.registerProperties(BlockType.FiltersAddon, FiltersAddonConfigComponent); - this.registerProperties(BlockType.DocumentsSourceAddon, SourceAddonConfigComponent); - this.registerProperties(BlockType.ReportItem, ReportItemConfigComponent); - this.registerProperties(BlockType.Calculate, CalculateConfigComponent); - this.registerProperties(BlockType.CalculateMathAddon, CalculateMathConfigComponent); - this.registerProperties(BlockType.ReassigningBlock, ReassigningConfigComponent); - } - - public register(type: BlockType, icon: string, name: string, title: string) { - this.blocks.push(type); + // Documents, Server Blocks + this.addBlock({ + type: BlockType.SendToGuardian, + icon: 'send', + name: 'Send', + title: `Add 'Send' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.ServerBlocks, + factory: null, + property: SendConfigComponent, + about: { + post: false, + get: false, + input: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + this.addBlock({ + type: BlockType.ExternalData, + icon: 'cloud', + name: 'External Data', + title: `Add 'External Data' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.ServerBlocks, + factory: null, + property: ExternalDataConfigComponent, + about: { + post: true, + get: false, + input: InputType.Single, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + return InputType.Single; + }, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + this.addBlock({ + type: BlockType.AggregateDocument, + icon: 'calendar_month', + name: 'Aggregate Data', + title: `Add 'Aggregate' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.ServerBlocks, + factory: null, + property: AggregateConfigComponent, + about: { + post: false, + get: false, + input: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + return InputType.Multiple; + }, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + this.addBlock({ + type: BlockType.ReassigningBlock, + icon: 'content_copy', + name: 'Reassigning', + title: `Add 'Reassigning' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.ServerBlocks, + factory: null, + property: ReassigningConfigComponent, + about: { + post: false, + get: false, + input: InputType.Single, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + return InputType.Single; + }, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + + // Documents, Addons + this.addBlock({ + type: BlockType.FiltersAddon, + icon: 'filter_alt', + name: 'Filters Addon', + title: `Add 'Filters' Addon`, + group: BlockGroup.Documents, + header: BlockHeaders.Addons, + factory: FiltersAddonBlockComponent, + property: FiltersAddonConfigComponent, + about: { + post: true, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Special, + control: ControlType.Special, + }, + allowedChildren: [ + { + type: BlockType.DocumentsSourceAddon, + group: BlockGroup.UnGrouped + } + ] + }); + this.addBlock({ + type: BlockType.DocumentsSourceAddon, + icon: 'source', + name: 'Source', + title: `Add 'DocumentsSourceAddon' Addon`, + group: BlockGroup.Documents, + header: BlockHeaders.Addons, + factory: null, + property: SourceAddonConfigComponent, + about: { + post: false, + get: false, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Special, + control: ControlType.Special, + }, + allowedChildren: [ + { + type: BlockType.FiltersAddon, + group: BlockGroup.UnGrouped + } + ] + }); + this.addBlock({ + type: BlockType.PaginationAddon, + icon: 'pages', + name: 'Pagination', + title: `Add 'Pagination' Addon`, + group: BlockGroup.Documents, + header: BlockHeaders.Addons, + factory: PaginationAddonBlockComponent, + property: null, + about: { + post: true, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.Special, + } + }); + this.addBlock({ + type: BlockType.TimerBlock, + icon: 'schedule', + name: 'Timer', + title: `Add 'Timer' Block`, + group: BlockGroup.Documents, + header: BlockHeaders.Addons, + factory: null, + property: TimerConfigComponent, + about: { + post: false, + get: false, + input: InputType.Single, + output: function (block: any, prev?: IBlockAbout, next?: boolean): InputType { + if (next === false) { + return InputType.None; + } + return InputType.Single; + }, + children: ChildrenType.None, + control: ControlType.Special, + } + }); + + // Tokens, Server Blocks + this.addBlock({ + type: BlockType.Mint, + icon: 'paid', + name: 'Mint', + title: `Add 'Mint' Block`, + group: BlockGroup.Tokens, + header: BlockHeaders.ServerBlocks, + factory: null, + property: MintConfigComponent, + about: { + post: false, + get: false, + input: InputType.Any, + output: InputType.Any, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + this.addBlock({ + type: BlockType.Wipe, + icon: 'delete', + name: 'Wipe', + title: `Add 'Wipe' Block`, + group: BlockGroup.Tokens, + header: BlockHeaders.ServerBlocks, + factory: null, + property: MintConfigComponent, + about: { + post: false, + get: false, + input: InputType.Any, + output: InputType.Any, + children: ChildrenType.None, + control: ControlType.Server, + } + }); + + // Calculate, Server Blocks + this.addBlock({ + type: BlockType.Calculate, + icon: 'bar_chart', + name: 'Calculate', + title: `Add 'Calculate' Block`, + group: BlockGroup.Calculate, + header: BlockHeaders.ServerBlocks, + factory: null, + property: CalculateConfigComponent, + about: { + post: false, + get: false, + input: InputType.Any, + output: function (block: any): InputType { + return block.inputDocuments == "separate" ? + InputType.Multiple : InputType.Single; + }, + children: ChildrenType.Special, + control: ControlType.Server, + }, + allowedChildren: [ + { + type: BlockType.CalculateMathAddon, + group: BlockGroup.UnGrouped, + } + ] + }); + this.addBlock({ + type: BlockType.CustomLogicBlock, + icon: 'bar_chart', + name: 'Custom Logic', + title: `Add 'Custom Logic' Block`, + group: BlockGroup.Calculate, + header: BlockHeaders.ServerBlocks, + factory: null, + property: CustomLogicConfigComponent, + about: { + post: false, + get: false, + input: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + output: function (block: any, prev?: IBlockAbout, next?: boolean): InputType { + if (next === false) { + return InputType.None; + } + if (prev && prev.output != InputType.None) { + return prev.output; + } + return InputType.Single; + }, + children: ChildrenType.Special, + control: ControlType.Server, + } + }); + + // Calculate, Addons + this.addBlock({ + type: BlockType.CalculateMathAddon, + icon: 'calculate', + name: 'Math Addon', + title: `Add 'Math' Addon`, + group: BlockGroup.Calculate, + header: BlockHeaders.Addons, + factory: null, + property: CalculateMathConfigComponent, + about: { + post: false, + get: false, + input: InputType.Single, + output: function (block: any, prev?: IBlockAbout, next?: boolean) { + if (next === false) { + return InputType.None; + } + return InputType.Single; + }, + children: ChildrenType.None, + control: ControlType.Special, + } + }); + + // Report, UIComponents + this.addBlock({ + type: BlockType.Report, + icon: 'addchart', + name: 'Report', + title: `Add 'Report' Block`, + group: BlockGroup.Report, + header: BlockHeaders.UIComponents, + factory: ReportBlockComponent, + property: null, + about: { + post: true, + get: true, + input: InputType.None, + output: InputType.None, + children: ChildrenType.Special, + control: ControlType.UI, + }, + allowedChildren: [ + { + type: BlockType.ReportItem, + group: BlockGroup.UnGrouped + } + ] + }); + + // Report, Addons + this.addBlock({ + type: BlockType.ReportItem, + icon: 'list_alt', + name: 'Report Item', + title: `Add 'Report Item' Block`, + group: BlockGroup.Report, + header: BlockHeaders.Addons, + factory: null, + property: ReportItemConfigComponent, + about: { + post: false, + get: false, + input: InputType.None, + output: InputType.None, + children: ChildrenType.None, + control: ControlType.Special, + } + }); + } + + public addBlock(setting: IBlockSetting) { + this.register( + setting.type, + setting.icon, + setting.name, + setting.title, + setting.allowedChildren, + setting.group, + setting.header + ); + + if (setting.factory) { + this.registerFactory(setting.type, setting.factory); + } + + if (setting.property) { + this.registerProperties(setting.type, setting.property); + } + + if (setting.about) { + this.registerAbout(setting.type, setting.about); + } + } + + public register( + type: BlockType, + icon: string, + name: string, + title: string, + allowedChildren: ChildrenDisplaySettings[] = [], + group: BlockGroup = BlockGroup.UnGrouped, + header?: BlockHeaders + ) { + this.blocks[type] = { + type, group, header + }; this.icons[type] = icon; this.names[type] = name; this.titles[type] = title; + this.allowedChildren[type] = allowedChildren; } public getIcon(blockType: string): string { @@ -171,17 +899,6 @@ export class RegisteredBlocks { return this.titles[blockType] || ''; } - public registerGroup(group: BlockGroup, type: BlockType) { - if (!this.groups[group]) { - this.groups[group] = []; - } - this.groups[group].push({ - type: type, - icon: this.getIcon(type), - name: this.getName(type), - title: this.getTitle(type) - }); - } public registerFactory(type: BlockType, factory: any) { this.factories[type] = factory; @@ -199,10 +916,25 @@ export class RegisteredBlocks { return this.properties[blockType]; } - public newBlock(type: BlockType, permissions: any, index: any): BlockNode { + + public registerAbout(type: BlockType, about: IBlockAboutConfig) { + this.about[type] = new BlockAbout(about); + } + + public getAbout(blockType: string, block: any): IBlockAbout { + const f: BlockAbout = this.about[blockType] || this.defaultA; + return f.get(block); + } + + public bindAbout(blockType: string, block: any, prev?: IBlockAbout, next?: boolean): IBlockAbout { + const f: BlockAbout = this.about[blockType] || this.defaultA; + return f.bind(block, prev, next); + } + + public newBlock(type: BlockType, permissions: any): BlockNode { return { id: this.generateUUIDv4(), - tag: `Block_${index}`, + tag: `Block`, blockType: type, defaultActive: !!this.factories[type], children: [], diff --git a/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.css b/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.css index f25bd58240..79f76eaddd 100644 --- a/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.css +++ b/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.css @@ -110,7 +110,7 @@ form { position: absolute; left: 0; right: 0; - top: 30px; + top: 0; bottom: 0; background: #fff; z-index: 1; diff --git a/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.html b/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.html index c8c3b1e925..9b94c5ed1d 100644 --- a/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.html +++ b/frontend/src/app/schema-engine/import-schema/import-schema-dialog.component.html @@ -1,29 +1,33 @@
- -

- Enter hedera message timestamp -

-
-
- - Message timestamp - - -
- - -
- -
+ + + + + +

+ Enter hedera message timestamp +

+
+
+ + Message timestamp + + +
+ + +
+ +
+
-
-
@@ -149,8 +149,8 @@ class="boolean-form-field" > - True - False + True + False Unset
diff --git a/frontend/src/app/schema-engine/schema-form-view/schema-form-view.component.ts b/frontend/src/app/schema-engine/schema-form-view/schema-form-view.component.ts index b26003886d..7153f58ba5 100644 --- a/frontend/src/app/schema-engine/schema-form-view/schema-form-view.component.ts +++ b/frontend/src/app/schema-engine/schema-form-view/schema-form-view.component.ts @@ -70,13 +70,11 @@ export class SchemaFormViewComponent implements OnInit { isInvalidType: false } if (!field.isArray && !field.isRef) { - let value = ""; - - if (this.values) { - value = this.values[item.name]; - } - - item.value = value || ""; + item.value = !this.values + || this.values[item.name] === null + || this.values[item.name] === undefined + ? "" + : this.values[item.name]; } if (!field.isArray && field.isRef) { item.fields = field.fields; @@ -84,7 +82,10 @@ export class SchemaFormViewComponent implements OnInit { if (field.isArray && !field.isRef) { let value = []; - if (this.values && this.values[item.name]) { + if (this.values + && this.values[item.name] !== null + && this.values[item.name] !== undefined + ) { const fieldValue = this.values[item.name]; if (Array.isArray(fieldValue)) { value = fieldValue; diff --git a/frontend/src/app/schema-engine/schema-form/schema-form.component.html b/frontend/src/app/schema-engine/schema-form/schema-form.component.html index f1ba91d489..d81554442e 100644 --- a/frontend/src/app/schema-engine/schema-form/schema-form.component.html +++ b/frontend/src/app/schema-engine/schema-form/schema-form.component.html @@ -1,224 +1,231 @@
- - -
-
-
- arrow_circle_right - - {{GetInvalidMessageByFieldType(item.format || item.type)}} - -
-
* Required
-
{{item.description}}
- - - - -
- -
- - - - + + +
+
+
+ arrow_circle_right + + {{GetInvalidMessageByFieldType(item.format || item.type)}} + +
+
* Required
+
{{item.description}}
+ + + + +
+ +
+ + + + +
+
+
+ + + + + + + Choose a date & time + + + + + + + Choose a date + + + + + +
+ + True + False + Unset + +
-
- - - - - - - - Choose a date & time - - - - - - - Choose a date - - - - - -
- - True - False - Unset - -
-
- -
-
- arrow_circle_right - - Please make sure all fields in schema contain a valid value - -
-
* Required
-
{{item.description}}
-
-
- - -
-
-
- - add Add Entity - -
-
- - remove Remove Entity - -
-
- -
-
- arrow_circle_right - - {{GetInvalidMessageByFieldType(item.format || item.type, true)}} - -
-
* Required
-
{{item.description}}
-
-
- - - - -
- -
- - - - + +
+
+ arrow_circle_right + + Please make sure all fields in schema contain a valid value + +
+
* Required
+
{{item.description}}
+
+
+ + +
+
+
+ + add Add Entity + +
+
+ + remove Remove Entity +
-
- - - - - - - - Choose a date & time - - - - - - - Choose a date - - - - - -
- - True - False - Unset -
-
-
- delete -
-
-
- - add Add Field - -
-
- -
-
- arrow_circle_right - - Please make sure all fields in schemas contain a valid value - -
-
* Required
-
{{item.description}}
-
-
- - -
- - remove Remove Entity - +
+
+ arrow_circle_right + + {{GetInvalidMessageByFieldType(item.format || item.type, true)}} + +
+
* Required
+
{{item.description}}
+
+
+ + + + +
+ +
+ + + + +
+
+
+ + + + + + + Choose a date & time + + + + + + + Choose a date + + + + + +
+ + True + False + Unset + + +
+ +
+
+ delete +
+
+
+ + add Add Field + +
-
-
-
-
-
-
- - add Add Entity - + +
+
+ arrow_circle_right + + Please make sure all fields in schemas contain a valid value + +
+
* Required
+
{{item.description}}
+
+
+ + +
+ + remove Remove Entity + +
+
+
+
+
+
+
+ + add Add Entity + +
+
+
-
- -
- -
- - -
- - - + +
+ + +
+ + + + + +
-
-
- + \ No newline at end of file diff --git a/frontend/src/app/views/admin/service-status/service-status.component.css b/frontend/src/app/views/admin/service-status/service-status.component.css index 978d7de307..b61ec314d5 100644 --- a/frontend/src/app/views/admin/service-status/service-status.component.css +++ b/frontend/src/app/views/admin/service-status/service-status.component.css @@ -1,30 +1,31 @@ -.status-container { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; +.name-column { font-size: xx-large; - width: 100%; - height: 60%; } -.service-status-container { - display: flex; - align-items: center; - justify-content: center; - gap: 20px; +.icon-status, .equal-column { + font-size: 40px; } -.status-container > .service-status-container > .icon-status { - font-size: 40px; +.icon-status { width: 40px; height: 40px; } +.service-status-row, .service-status-row td { + padding: 0 10px; +} + .ready-status { color: green; } .stopped-status { color: red; +} + +.service-status-container { + display: flex; + align-items: center; + justify-content: center; + height: 60%; } \ No newline at end of file diff --git a/frontend/src/app/views/admin/service-status/service-status.component.html b/frontend/src/app/views/admin/service-status/service-status.component.html index 5081105722..94d19d9390 100644 --- a/frontend/src/app/views/admin/service-status/service-status.component.html +++ b/frontend/src/app/views/admin/service-status/service-status.component.html @@ -1,10 +1,15 @@ -
-
- {{service.serviceName}} - - check - - - close -
+
+
+ expand_more Meta DataAbout
Type {{block.blockType}}
GET + {{about.get?'Yes':'No'}} +
POST + {{about.post?'Yes':'No'}} +
Server Input + {{about.input}} +
Server Output + {{about.output}} +
Control Type + {{about.control}} +
Children + {{about.children}} +
+ + expand_more + + Meta Data
TagOn errors - {{item.label}} + {{item.label}} +
+ + + + + +
{{service.serviceName}}- + check + + + close +
\ No newline at end of file diff --git a/frontend/src/app/views/header/header.component.css b/frontend/src/app/views/header/header.component.css index aa34404deb..a02ce8fec9 100644 --- a/frontend/src/app/views/header/header.component.css +++ b/frontend/src/app/views/header/header.component.css @@ -3,7 +3,7 @@ } .nav-bar { - padding: 0px 60px; + padding: 0px 120px 0px 30px; } .content { @@ -27,6 +27,8 @@ color: #fff; opacity: 1; transition: color .3s linear; + padding: 0 10px; + min-width: 140px; } ::ng-deep .mat-toolbar-row, @@ -101,8 +103,9 @@ a[hidden="true"] { } .debug-user button { - width: 48%; - margin: 5px 1%; + width: 145px; + padding: 0 15px; + margin: 5px 4px; } .debug-user { diff --git a/frontend/src/app/views/header/header.component.html b/frontend/src/app/views/header/header.component.html index 7ed7a0215f..09fa854c9e 100644 --- a/frontend/src/app/views/header/header.component.html +++ b/frontend/src/app/views/header/header.component.html @@ -33,17 +33,21 @@
+ background: white; + max-height: 345px; + height: auto; + width: 470px; + border-radius: 30px; + overflow: scroll;">
- + + + + +
- - Root Authority - + + Root Authority: + {{user.username}} diff --git a/guardian-service/.env.docker b/guardian-service/.env.docker index dd465b6f42..a407b0e5f9 100644 --- a/guardian-service/.env.docker +++ b/guardian-service/.env.docker @@ -5,4 +5,4 @@ DB_DATABASE="guardian_db" MAX_TRANSACTION_FEE="10" INITIAL_BALANCE="30" OPERATOR_ID="..." -OPERATOR_KEY="..." \ No newline at end of file +OPERATOR_KEY="..." diff --git a/guardian-service/Dockerfile b/guardian-service/Dockerfile index e0ece27b69..0185fba7c1 100644 --- a/guardian-service/Dockerfile +++ b/guardian-service/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/logger-helper COPY ./logger-helper/package*.json ./ COPY ./logger-helper/tsconfig.json ./ diff --git a/guardian-service/nodemon.json b/guardian-service/nodemon.json new file mode 100644 index 0000000000..8b879fd87b --- /dev/null +++ b/guardian-service/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist", "../logger-helper/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/guardian-service/package-lock.json b/guardian-service/package-lock.json index d71a2357f1..e571b919a7 100644 --- a/guardian-service/package-lock.json +++ b/guardian-service/package-lock.json @@ -1,12 +1,12 @@ { "name": "guardian-service", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "guardian-service", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "@hashgraph/did-sdk-js": "0.1.1", @@ -22,15 +22,14 @@ "ajv-formats": "^2.1.1", "axios": "^0.25.0", "bs58": "^4.0.1", + "common": "file:../common", "cors": "^2.8.5", + "cron": "^2.0.0", "deep-equal": "^2.0.5", "dotenv": "^16.0.0", "express": "^4.17.1", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", - "jose": "4.3.8", - "js-base64": "^3.6.1", "jszip": "^3.7.1", "logger-helper": "file:../logger-helper", "mathjs": "^10.1.0", @@ -55,8 +54,23 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" @@ -69,10 +83,10 @@ } }, "../logger-helper": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces" }, "devDependencies": { @@ -3781,11 +3795,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/blueimp-md5": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", @@ -4037,14 +4046,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -4462,6 +4463,10 @@ "node": ">= 10" } }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -4614,6 +4619,14 @@ "node": ">= 0.10" } }, + "node_modules/cron": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-2.0.0.tgz", + "integrity": "sha512-RPeRunBCFr/WEo7WLp8Jnm45F/ziGJiHVvVQEBSDTSGu6uHW49b2FOP2O14DcXlGJRLhwE7TIoDzHHK4KmlL6g==", + "dependencies": { + "luxon": "^1.23.x" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4883,11 +4896,6 @@ "node": ">=12" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -5450,11 +5458,6 @@ "node": ">=6" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "node_modules/expo": { "version": "44.0.6", "resolved": "https://registry.npmjs.org/expo/-/expo-44.0.6.tgz", @@ -5750,27 +5753,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -6325,11 +6307,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -6852,11 +6829,6 @@ "node": ">=4" } }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interfaces": { "resolved": "../interfaces", "link": true @@ -7680,7 +7652,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true }, "node_modules/lodash._reinterpolate": { "version": "3.0.0", @@ -7823,6 +7796,14 @@ "node": ">=10" } }, + "node_modules/luxon": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==", + "engines": { + "node": "*" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -8541,11 +8522,6 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/node-pre-gyp": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", @@ -14681,11 +14657,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "blueimp-md5": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", @@ -14881,14 +14852,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -15195,6 +15158,18 @@ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "peer": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -15323,6 +15298,14 @@ "vary": "^1" } }, + "cron": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-2.0.0.tgz", + "integrity": "sha512-RPeRunBCFr/WEo7WLp8Jnm45F/ziGJiHVvVQEBSDTSGu6uHW49b2FOP2O14DcXlGJRLhwE7TIoDzHHK4KmlL6g==", + "requires": { + "luxon": "^1.23.x" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -15520,11 +15503,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -15962,11 +15940,6 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "expo": { "version": "44.0.6", "resolved": "https://registry.npmjs.org/expo/-/expo-44.0.6.tgz", @@ -16220,24 +16193,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -16662,11 +16617,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -17063,11 +17013,6 @@ } } }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interfaces": { "version": "file:../interfaces", "requires": { @@ -17668,7 +17613,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true }, "lodash._reinterpolate": { "version": "3.0.0", @@ -17768,7 +17714,7 @@ "version": "file:../logger-helper", "requires": { "@types/node": "^17.0.13", - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces", "mocha-junit-reporter": "^2.0.2", "tslint": "^6.1.3", @@ -17803,6 +17749,11 @@ "yallist": "^4.0.0" } }, + "luxon": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -18379,11 +18330,6 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node-pre-gyp": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", diff --git a/guardian-service/package.json b/guardian-service/package.json index f3c202be1f..35c4237e96 100644 --- a/guardian-service/package.json +++ b/guardian-service/package.json @@ -20,27 +20,26 @@ "@transmute/jsonld-schema": "0.7.0-unstable.40", "@transmute/security-context": "0.7.0-unstable.40", "@transmute/vc.js": "0.7.0-unstable.40", - "bs58": "^4.0.1", - "js-base64": "^3.6.1", "ajv": "^8.10.0", "ajv-formats": "^2.1.1", "axios": "^0.25.0", - "jose": "4.3.8", + "bs58": "^4.0.1", + "common": "file:../common", "cors": "^2.8.5", + "cron": "^2.0.0", "deep-equal": "^2.0.5", "dotenv": "^16.0.0", "express": "^4.17.1", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", "jszip": "^3.7.1", + "logger-helper": "file:../logger-helper", "mathjs": "^10.1.0", "module-alias": "^2.2.2", + "moment": "^2.29.1", "mongodb": "^4.2.1", "reflect-metadata": "^0.1.13", - "typeorm": "^0.2.41", - "moment": "^2.29.1", - "logger-helper": "file:../logger-helper" + "typeorm": "^0.2.41" }, "description": "", "devDependencies": { @@ -63,12 +62,13 @@ "scripts": { "build": "tsc", "debug": "nodemon dist/index.js", + "dev:docker": "nodemon .", "dev": "tsc -w", "lint": "tslint --project .", "start": "node dist/index.js", - "test": "mocha tests/unit-tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/guardian-service.xml", + "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/guardian-service.xml", "test:network": "mocha tests/network-tests/**/*.test.js", "test:stability": "mocha tests/stability.test.js" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/guardian-service/src/api/api-response.ts b/guardian-service/src/api/api-response.ts index f9e7c488c3..b8eaf37dfc 100644 --- a/guardian-service/src/api/api-response.ts +++ b/guardian-service/src/api/api-response.ts @@ -1,12 +1,14 @@ -import { ApplicationState, ApplicationStates, MessageInitialization } from 'interfaces'; +import { MessageBrokerChannel, MessageResponse, ApplicationState, MessageInitialization } from "common"; +import { ApplicationStates } from "interfaces"; -export function ApiResponse(channel: any, event: any, cb: (msg, res) => Promise): void { +export function ApiResponse(channel: MessageBrokerChannel, event: any, handleFunc: (msg) => Promise>): void { const state = new ApplicationState(); - channel.response(event, async (msg, res) => { + channel.response(event, async (msg) => { if (state.getState() !== ApplicationStates.READY) { - res.send(new MessageInitialization()); - return; + console.warn(`${state.getState()} state, waiting for ${ApplicationStates.READY} state, event ${event}`); + return new MessageInitialization() } - await cb(msg, res); + + return await handleFunc(msg); }) } diff --git a/guardian-service/src/api/approve.service.ts b/guardian-service/src/api/approve.service.ts index b3a47ca409..729e15e594 100644 --- a/guardian-service/src/api/approve.service.ts +++ b/guardian-service/src/api/approve.service.ts @@ -1,7 +1,8 @@ import { ApprovalDocument } from '@entity/approval-document'; -import { IApprovalDocument, MessageAPI, MessageResponse } from 'interfaces'; import { MongoRepository } from 'typeorm'; import { ApiResponse } from '@api/api-response'; +import { MessageBrokerChannel, MessageResponse } from 'common'; +import { MessageAPI, IApprovalDocument } from 'interfaces'; /** * Connecting to the message broker methods of working with Approve documents. @@ -10,7 +11,7 @@ import { ApiResponse } from '@api/api-response'; * @param approvalDocumentRepository - table with approve documents */ export const approveAPI = async function ( - channel: any, + channel: MessageBrokerChannel, approvalDocumentRepository: MongoRepository ): Promise { /** @@ -24,13 +25,13 @@ export const approveAPI = async function ( * * @returns {IApprovalDocument[]} - approve documents */ - ApiResponse(channel, MessageAPI.GET_APPROVE_DOCUMENTS, async (msg, res) => { - if (msg.payload.id) { - const document = await approvalDocumentRepository.findOne(msg.payload.id); - res.send(new MessageResponse([document])); + ApiResponse(channel, MessageAPI.GET_APPROVE_DOCUMENTS, async (msg) => { + if (msg.id) { + const document = await approvalDocumentRepository.findOne(msg.id); + return new MessageResponse([document]); } else { const reqObj: any = { where: {} }; - const { owner, approver, id, hash, policyId, schema, issuer, ...otherArgs } = msg.payload; + const { owner, approver, id, hash, policyId, schema, issuer, ...otherArgs } = msg; if (owner) { reqObj.where['owner'] = { $eq: owner } } @@ -57,7 +58,7 @@ export const approveAPI = async function ( } Object.assign(reqObj.where, otherArgs); const documents: IApprovalDocument[] = await approvalDocumentRepository.find(reqObj); - res.send(new MessageResponse(documents)); + return new MessageResponse(documents); } }); @@ -68,19 +69,19 @@ export const approveAPI = async function ( * * @returns {IApprovalDocument[]} - new approve documents */ - ApiResponse(channel, MessageAPI.SET_APPROVE_DOCUMENTS, async (msg, res) => { - const id = msg.payload.id; + ApiResponse(channel, MessageAPI.SET_APPROVE_DOCUMENTS, async (msg) => { + const id = msg.id; let result; if (id) { - const documentObject = msg.payload; + const documentObject = msg; const id = documentObject.id; delete documentObject.id; result = await approvalDocumentRepository.update(id, documentObject); } else { - const documentObject = approvalDocumentRepository.create(msg.payload); + const documentObject = approvalDocumentRepository.create(msg); result = await approvalDocumentRepository.save(documentObject) } - res.send(new MessageResponse(result)); + return new MessageResponse(result); }) /** @@ -90,11 +91,11 @@ export const approveAPI = async function ( * * @returns {IApprovalDocument} - new approve document */ - ApiResponse(channel, MessageAPI.UPDATE_APPROVE_DOCUMENTS, async (msg, res) => { - const documentObject = msg.payload; + ApiResponse(channel, MessageAPI.UPDATE_APPROVE_DOCUMENTS, async (msg) => { + const documentObject = msg; const id = documentObject.id; delete documentObject.id; const result = await approvalDocumentRepository.update(id, documentObject); - res.send(new MessageResponse(result)); + return new MessageResponse(result); }) } diff --git a/guardian-service/src/api/config.service.ts b/guardian-service/src/api/config.service.ts index 80ec5739e4..f8b85370b5 100644 --- a/guardian-service/src/api/config.service.ts +++ b/guardian-service/src/api/config.service.ts @@ -1,9 +1,10 @@ import { Settings } from '@entity/settings'; import { Topic } from '@entity/topic'; -import { CommonSettings, IRootConfig, MessageAPI, MessageError, MessageResponse } from 'interfaces'; import { Logger } from 'logger-helper'; import { MongoRepository } from 'typeorm'; import { ApiResponse } from '@api/api-response'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { MessageAPI, CommonSettings } from 'interfaces'; /** * Connecting to the message broker methods of working with root address book. @@ -12,22 +13,22 @@ import { ApiResponse } from '@api/api-response'; * @param approvalDocumentRepository - table with approve documents */ export const configAPI = async function ( - channel: any, + channel: MessageBrokerChannel, settingsRepository: MongoRepository, topicRepository: MongoRepository, ): Promise { - ApiResponse(channel, MessageAPI.GET_TOPIC, async (msg, res) => { - const topic = await topicRepository.findOne(msg.payload); - res.send(new MessageResponse(topic)); + ApiResponse(channel, MessageAPI.GET_TOPIC, async (msg) => { + const topic = await topicRepository.findOne(msg); + return new MessageResponse(topic); }); /** * Update settings * */ - ApiResponse(channel, MessageAPI.UPDATE_SETTINGS, async (msg, res) => { + ApiResponse(channel, MessageAPI.UPDATE_SETTINGS, async (msg) => { try { - const settings = msg.payload as CommonSettings; + const settings = msg as CommonSettings; const oldOperatorId = await settingsRepository.findOne({ name: 'OPERATOR_ID' }); @@ -61,11 +62,11 @@ export const configAPI = async function ( value: settings.operatorKey }); } - res.send(new MessageResponse(null)); + return new MessageResponse(null); } catch (e) { new Logger().error(e.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(e)) + return new MessageError(e); } }); @@ -73,7 +74,7 @@ export const configAPI = async function ( * Get settings * */ - ApiResponse(channel, MessageAPI.GET_SETTINGS, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_SETTINGS, async (msg) => { try { const operatorId = await settingsRepository.findOne({ name: 'OPERATOR_ID' @@ -81,14 +82,14 @@ export const configAPI = async function ( const operatorKey = await settingsRepository.findOne({ name: 'OPERATOR_KEY' }); - res.send(new MessageResponse({ + return new MessageResponse({ operatorId: operatorId?.value || process.env.OPERATOR_ID, operatorKey: operatorKey?.value || process.env.OPERATOR_KEY - })); + }); } catch (e) { new Logger().error(e.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(e)) + return new MessageError(e); } }); } diff --git a/guardian-service/src/api/demo.ts b/guardian-service/src/api/demo.ts index 757ea25b60..29d9de5dc1 100644 --- a/guardian-service/src/api/demo.ts +++ b/guardian-service/src/api/demo.ts @@ -1,16 +1,17 @@ -import { MessageAPI, MessageError, MessageResponse } from 'interfaces'; import { Logger } from 'logger-helper'; import { getMongoRepository, MongoRepository } from 'typeorm'; import { Settings } from '@entity/settings'; import { HederaSDKHelper } from '@hedera-modules'; import { ApiResponse } from '@api/api-response'; import { Policy } from '@entity/policy'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { MessageAPI } from 'interfaces'; export const demoAPI = async function ( - channel: any, + channel: MessageBrokerChannel, settingsRepository: MongoRepository ): Promise { - ApiResponse(channel, MessageAPI.GENERATE_DEMO_KEY, async (msg, res) => { + ApiResponse(channel, MessageAPI.GENERATE_DEMO_KEY, async (msg) => { try { const operatorId = await settingsRepository.findOne({ name: 'OPERATOR_ID' @@ -22,23 +23,23 @@ export const demoAPI = async function ( const OPERATOR_KEY = operatorKey?.value || process.env.OPERATOR_KEY; const client = new HederaSDKHelper(OPERATOR_ID, OPERATOR_KEY); const treasury = await client.newAccount(); - res.send(new MessageResponse({ + return new MessageResponse({ id: treasury.id.toString(), key: treasury.key.toString() - })); + }); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }); - ApiResponse(channel, MessageAPI.GET_USER_ROLES, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_USER_ROLES, async (msg) => { try { - const did = msg.payload.did; + const did = msg.did; const policies = await getMongoRepository(Policy).find(); const result = []; policies.forEach(p => { - if(p.registeredUsers[did]) { + if (p.registeredUsers[did]) { result.push({ name: p.name, version: p.version, @@ -47,10 +48,10 @@ export const demoAPI = async function ( } }); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }) } diff --git a/guardian-service/src/api/documents.service.ts b/guardian-service/src/api/documents.service.ts index fffaab3e37..02fa75a0dc 100644 --- a/guardian-service/src/api/documents.service.ts +++ b/guardian-service/src/api/documents.service.ts @@ -10,11 +10,10 @@ import { IVCDocument, IVPDocument, MessageAPI, - MessageError, - MessageResponse } from 'interfaces'; import { MongoRepository } from 'typeorm'; import { ApiResponse } from '@api/api-response'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; /** * Connect to the message broker methods of working with VC, VP and DID Documents @@ -26,7 +25,7 @@ import { ApiResponse } from '@api/api-response'; * @param vc - verification methods VC and VP Documents */ export const documentsAPI = async function ( - channel: any, + channel: MessageBrokerChannel, didDocumentRepository: MongoRepository, vcDocumentRepository: MongoRepository, vpDocumentRepository: MongoRepository, @@ -77,10 +76,10 @@ export const documentsAPI = async function ( * * @returns {IDidDocument[]} - DID Documents */ - ApiResponse(channel, MessageAPI.GET_DID_DOCUMENTS, async (msg, res) => { - const reqObj = { where: { did: { $eq: msg.payload.did } } }; + ApiResponse(channel, MessageAPI.GET_DID_DOCUMENTS, async (msg) => { + const reqObj = { where: { did: { $eq: msg.did } } }; const didDocuments: IDidObject[] = await didDocumentRepository.find(reqObj); - res.send(new MessageResponse(didDocuments)); + return new MessageResponse(didDocuments); }); /** @@ -96,11 +95,11 @@ export const documentsAPI = async function ( * * @returns {IVCDocument[]} - VC Documents */ - ApiResponse(channel, MessageAPI.GET_VC_DOCUMENTS, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_VC_DOCUMENTS, async (msg) => { try { - if (msg.payload) { + if (msg) { const reqObj: any = { where: {} }; - const { owner, assign, issuer, id, hash, policyId, schema, ...otherArgs } = msg.payload; + const { owner, assign, issuer, id, hash, policyId, schema, ...otherArgs } = msg; if (owner) { reqObj.where['owner'] = { $eq: owner } } @@ -127,14 +126,14 @@ export const documentsAPI = async function ( } Object.assign(reqObj.where, otherArgs); const vcDocuments: IVCDocument[] = await vcDocumentRepository.find(reqObj); - res.send(new MessageResponse(vcDocuments)); + return new MessageResponse(vcDocuments); } else { const vcDocuments: IVCDocument[] = await vcDocumentRepository.find(); - res.send(new MessageResponse(vcDocuments)); + return new MessageResponse(vcDocuments); } } catch (e) { - res.send(new MessageError(e.message)); + return new MessageError(e.message); } }); @@ -147,22 +146,22 @@ export const documentsAPI = async function ( * * @returns {IDidDocument} - new DID Document */ - ApiResponse(channel, MessageAPI.SET_DID_DOCUMENT, async (msg, res) => { - if (msg.payload.did && msg.payload.operation) { - const did = msg.payload.did; - const operation = msg.payload.operation; + ApiResponse(channel, MessageAPI.SET_DID_DOCUMENT, async (msg) => { + if (msg.did && msg.operation) { + const did = msg.did; + const operation = msg.operation; const item = await didDocumentRepository.findOne({ did: did }); if (item) { item.status = getDIDOperation(operation); const result: IDidObject = await didDocumentRepository.save(item); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } else { - res.send(new MessageError('Document not found')); + return new MessageError('Document not found'); } } else { - const didDocumentObject = didDocumentRepository.create(msg.payload); + const didDocumentObject = didDocumentRepository.create(msg); const result: IDidObject[] = await didDocumentRepository.save(didDocumentObject); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } }); @@ -175,42 +174,41 @@ export const documentsAPI = async function ( * * @returns {IVCDocument} - new VC Document */ - ApiResponse(channel, MessageAPI.SET_VC_DOCUMENT, async (msg, res) => { + ApiResponse(channel, MessageAPI.SET_VC_DOCUMENT, async (msg) => { let result: IVCDocument; - const hash = msg.payload.hash; + const hash = msg.hash; if (hash) { result = await vcDocumentRepository.findOne({ hash: hash }); } if (result) { - const operation = msg.payload.operation; + const operation = msg.operation; if (operation) { result.hederaStatus = getVCOperation(operation); } - const assign = msg.payload.assign; + const assign = msg.assign; if (assign) { result.assign = assign; } - const type = msg.payload.type; + const type = msg.type; if (type) { result.type = type; } - const option = msg.payload.option; + const option = msg.option; if (option) { result.option = option; } } if (!result) { - if (msg.payload.document) { - result = vcDocumentRepository.create(msg.payload as VcDocument); + if (msg.document) { + result = vcDocumentRepository.create(msg as VcDocument); } else { - res.send(new MessageError('Invalid document')); - return; + return new MessageError('Invalid document'); } } @@ -228,7 +226,7 @@ export const documentsAPI = async function ( result.signature = verify ? DocumentSignature.VERIFIED : DocumentSignature.INVALID; result = await vcDocumentRepository.save(result); - res.send(new MessageResponse(result)); + return new MessageResponse(result); }); /** @@ -238,10 +236,10 @@ export const documentsAPI = async function ( * * @returns {IVPDocument} - new VP Document */ - ApiResponse(channel, MessageAPI.SET_VP_DOCUMENT, async (msg, res) => { - const vpDocumentObject = vpDocumentRepository.create(msg.payload); + ApiResponse(channel, MessageAPI.SET_VP_DOCUMENT, async (msg) => { + const vpDocumentObject = vpDocumentRepository.create(msg); const result: any = await vpDocumentRepository.save(vpDocumentObject); - res.send(new MessageResponse(result)); + return new MessageResponse(result); }); /** @@ -251,13 +249,13 @@ export const documentsAPI = async function ( * * @returns {IVPDocument[]} - VP Documents */ - ApiResponse(channel, MessageAPI.GET_VP_DOCUMENTS, async (msg, res) => { - if (msg.payload) { - const document: IVPDocument[] = await vpDocumentRepository.find(msg.payload); - res.send(new MessageResponse(document)); + ApiResponse(channel, MessageAPI.GET_VP_DOCUMENTS, async (msg) => { + if (msg) { + const document: IVPDocument[] = await vpDocumentRepository.find(msg); + return new MessageResponse(document); } else { const documents: IVPDocument[] = await vpDocumentRepository.find(); - res.send(new MessageResponse(documents)); + return new MessageResponse(documents); } }); } diff --git a/guardian-service/src/api/loader.service.ts b/guardian-service/src/api/loader.service.ts index 02e73de2eb..378941d19f 100644 --- a/guardian-service/src/api/loader.service.ts +++ b/guardian-service/src/api/loader.service.ts @@ -1,10 +1,11 @@ -import { MessageAPI, MessageError, MessageResponse } from 'interfaces'; import { Schema } from '@entity/schema'; import { MongoRepository } from 'typeorm'; import { DidDocument } from '@entity/did-document'; import { Logger } from 'logger-helper'; import { DidRootKey } from '@hedera-modules'; import { ApiResponse } from '@api/api-response'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { MessageAPI } from 'interfaces'; /** * Connect to the message broker methods of working with Documents Loader. @@ -14,7 +15,7 @@ import { ApiResponse } from '@api/api-response'; * @param schemaDocumentLoader - Schema Documents Loader */ export const loaderAPI = async function ( - channel: any, + channel: MessageBrokerChannel, didDocumentRepository: MongoRepository, schemaRepository: MongoRepository ): Promise { @@ -26,20 +27,19 @@ export const loaderAPI = async function ( * * @returns {any} - DID Document */ - ApiResponse(channel, MessageAPI.LOAD_DID_DOCUMENT, async (msg, res) => { + ApiResponse(channel, MessageAPI.LOAD_DID_DOCUMENT, async (msg) => { try { - const iri = msg.payload.did; + const iri = msg.did; const did = DidRootKey.create(iri).getController(); const reqObj = { where: { did: { $eq: did } } }; const didDocuments = await didDocumentRepository.findOne(reqObj); if (didDocuments) { - res.send(new MessageResponse(didDocuments.document)); - return; + return new MessageResponse(didDocuments.document); } - res.send(new MessageError('Document not found')); + return new MessageError('Document not found'); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -49,28 +49,27 @@ export const loaderAPI = async function ( * * @returns Schema document */ - ApiResponse(channel, MessageAPI.LOAD_SCHEMA_DOCUMENT, async (msg, res) => { + ApiResponse(channel, MessageAPI.LOAD_SCHEMA_DOCUMENT, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Document not found')); - return; + if (!msg) { + return new MessageError('Document not found'); } - if (Array.isArray(msg.payload)) { + if (Array.isArray(msg)) { const schema = await schemaRepository.find({ - where: { documentURL: { $in: msg.payload } } + where: { documentURL: { $in: msg } } }); - res.send(new MessageResponse(schema)); + return new MessageResponse(schema); } else { const schema = await schemaRepository.findOne({ - where: { documentURL: { $eq: msg.payload } } + where: { documentURL: { $eq: msg } } }); - res.send(new MessageResponse(schema)); + return new MessageResponse(schema); } } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -80,27 +79,26 @@ export const loaderAPI = async function ( * * @returns Schema context */ - ApiResponse(channel, MessageAPI.LOAD_SCHEMA_CONTEXT, async (msg, res) => { + ApiResponse(channel, MessageAPI.LOAD_SCHEMA_CONTEXT, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Document not found')) - return; + if (!msg) { + return new MessageError('Document not found'); } - if (Array.isArray(msg.payload)) { + if (Array.isArray(msg)) { const schema = await schemaRepository.find({ - where: { contextURL: { $in: msg.payload } } + where: { contextURL: { $in: msg } } }); - res.send(new MessageResponse(schema)); + return new MessageResponse(schema); } else { const schema = await schemaRepository.findOne({ - where: { contextURL: { $eq: msg.payload } } + where: { contextURL: { $eq: msg } } }); - res.send(new MessageResponse(schema)); + return new MessageResponse(schema); } } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); } diff --git a/guardian-service/src/api/profile.service.ts b/guardian-service/src/api/profile.service.ts index 8a21665d74..278a66cfc9 100644 --- a/guardian-service/src/api/profile.service.ts +++ b/guardian-service/src/api/profile.service.ts @@ -2,8 +2,6 @@ import { DidDocumentStatus, DocumentStatus, MessageAPI, - MessageError, - MessageResponse, SchemaEntity, TopicType } from 'interfaces'; @@ -26,19 +24,18 @@ import { DidDocument as DidDocumentCollection } from '@entity/did-document'; import { VcDocument as VcDocumentCollection } from '@entity/vc-document'; import { ApiResponse } from '@api/api-response'; import { TopicHelper } from '@helpers/topicHelper'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; /** * Connect to the message broker methods of working with Address books. - * + * * @param channel - channel - * @param configRepository - table with Address books - * @param didDocumentRepository - table with DID Documents - * @param vcDocumentRepository - table with VC Documents + * */ -export const profileAPI = async function (channel: any) { - ApiResponse(channel, MessageAPI.GET_USER_BALANCE, async (msg, res) => { +export const profileAPI = async function (channel: MessageBrokerChannel) { + ApiResponse(channel, MessageAPI.GET_USER_BALANCE, async (msg) => { try { - const { username } = msg.payload; + const { username } = msg; const wallet = new Wallet(); const users = new Users(); @@ -46,34 +43,32 @@ export const profileAPI = async function (channel: any) { const user = await users.getUser(username); if (!user) { - res.send(new MessageResponse('Invalid Account')); - return; + return new MessageResponse('Invalid Account'); } if (!user.hederaAccountId) { - res.send(new MessageResponse('Invalid Hedera Account Id')); - return; + return new MessageResponse('Invalid Hedera Account Id'); } const key = await wallet.getKey(user.walletToken, KeyType.KEY, user.did); const client = new HederaSDKHelper(user.hederaAccountId, key); const balance = await client.balance(user.hederaAccountId); - res.send(new MessageResponse(balance)); + return new MessageResponse(balance); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 500)); + return new MessageError(error.message, 500); } }) - ApiResponse(channel, MessageAPI.CREATE_USER_PROFILE, async (msg, res) => { + ApiResponse(channel, MessageAPI.CREATE_USER_PROFILE, async (msg) => { try { const { hederaAccountId, hederaAccountKey, parent, vcDocument - } = msg.payload; + } = msg; let topic: any, newTopic = false; if (parent) { @@ -135,7 +130,7 @@ export const profileAPI = async function (channel: any) { const messageServer = new MessageServer(hederaAccountId, hederaAccountKey); try { - const didMessageResult =await messageServer.setTopicObject(topic).sendMessage(didMessage) + const didMessageResult = await messageServer.setTopicObject(topic).sendMessage(didMessage) didDoc.status = DidDocumentStatus.CREATE; didDoc.messageId = didMessageResult.getId(); didDoc.topicId = didMessageResult.getTopicId(); @@ -144,7 +139,7 @@ export const profileAPI = async function (channel: any) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); didDoc.status = DidDocumentStatus.FAILED; - getMongoRepository(DidDocumentCollection).update(didDoc.id, didDoc); + await getMongoRepository(DidDocumentCollection).update(didDoc.id, didDoc); } if (vcMessage) { try { @@ -157,15 +152,15 @@ export const profileAPI = async function (channel: any) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); vcDoc.hederaStatus = DocumentStatus.FAILED; - getMongoRepository(VcDocumentCollection).update(vcDoc.id, vcDoc); + await getMongoRepository(VcDocumentCollection).update(vcDoc.id, vcDoc); } } - res.send(new MessageResponse(userDID)); + return new MessageResponse(userDID); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 500)); + return new MessageError(error.message, 500); } }) -} \ No newline at end of file +} diff --git a/guardian-service/src/api/schema.service.ts b/guardian-service/src/api/schema.service.ts index 8d089db500..f7bb6d9813 100644 --- a/guardian-service/src/api/schema.service.ts +++ b/guardian-service/src/api/schema.service.ts @@ -2,13 +2,11 @@ import { Schema as SchemaCollection } from '@entity/schema'; import { ISchema, MessageAPI, - MessageError, - MessageResponse, - ModelHelper, SchemaEntity, - SchemaHelper, SchemaStatus, - TopicType + TopicType, + SchemaHelper, + ModelHelper, } from 'interfaces'; import { getMongoRepository } from 'typeorm'; import { readJSON } from 'fs-extra'; @@ -21,6 +19,7 @@ import { Users } from '@helpers/users'; import { ApiResponse } from '@api/api-response'; import { Topic } from '@entity/topic'; import { TopicHelper } from '@helpers/topicHelper'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; export const schemaCache = {}; @@ -316,7 +315,7 @@ export async function publishSchema(id: string, version: string, owner: string): * @param channel - channel * @param schemaRepository - table with schemes */ -export const schemaAPI = async function (channel: any, schemaRepository): Promise { +export const schemaAPI = async function (channel: MessageBrokerChannel, schemaRepository): Promise { /** * Create schema @@ -325,17 +324,17 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.CREATE_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.CREATE_SCHEMA, async (msg) => { try { - const schemaObject = msg.payload as ISchema; + const schemaObject = msg as ISchema; console.log('c', schemaObject) SchemaHelper.setVersion(schemaObject, null, schemaObject.version); await createSchema(schemaObject, schemaObject.owner); const schemes = await schemaRepository.find(); - res.send(new MessageResponse(schemes)); + return new MessageResponse(schemes); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }); @@ -346,25 +345,25 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.UPDATE_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.UPDATE_SCHEMA, async (msg) => { try { - const id = msg.payload.id as string; + const id = msg.id as string; const item = await schemaRepository.findOne(id); if (item) { - item.name = msg.payload.name; - item.description = msg.payload.description; - item.entity = msg.payload.entity; - item.document = msg.payload.document; + item.name = msg.name; + item.description = msg.description; + item.entity = msg.entity; + item.document = msg.document; item.status = SchemaStatus.DRAFT; SchemaHelper.setVersion(item, null, item.version); SchemaHelper.updateIRI(item); await schemaRepository.update(item.id, item); } const schemes = await schemaRepository.find(); - res.send(new MessageResponse(schemes)); + return new MessageResponse(schemes); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }); @@ -375,17 +374,16 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.GET_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_SCHEMA, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Invalid load schema parameter')); - return; + if (!msg) { + return new MessageError('Invalid load schema parameter'); } - const schema = await schemaRepository.findOne(msg.payload.id); - res.send(new MessageResponse(schema)); + const schema = await schemaRepository.findOne(msg.id); + return new MessageResponse(schema); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }); @@ -396,14 +394,13 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.GET_SCHEMES, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_SCHEMES, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Invalid load schema parameter')); - return; + if (!msg) { + return new MessageError('Invalid load schema parameter'); } - const { owner, uuid, topicId, pageIndex, pageSize } = msg.payload; + const { owner, uuid, topicId, pageIndex, pageSize } = msg; const filter: any = { where: { readonly: false @@ -430,14 +427,14 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis filter.skip = _pageIndex * _pageSize; } - const result = await schemaRepository.findAndCount(filter); - res.send(new MessageResponse({ - schemes: result[0], - count: result[1] - })); + const [schemes, count] = await schemaRepository.findAndCount(filter); + return new MessageResponse({ + schemes, + count + }); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error)); + return new MessageError(error); } }); @@ -449,21 +446,21 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.PUBLISH_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.PUBLISH_SCHEMA, async (msg) => { try { - if (msg.payload) { - const id = msg.payload.id as string; - const version = msg.payload.version as string; - const owner = msg.payload.owner as string; + if (msg) { + const id = msg.id as string; + const version = msg.version as string; + const owner = msg.owner as string; const item = await publishSchema(id, version, owner); - res.send(new MessageResponse(item)); + return new MessageResponse(item); } else { - res.send(new MessageError('Invalid id')); + return new MessageError('Invalid id'); } } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -475,10 +472,10 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {ISchema[]} - all schemes */ - ApiResponse(channel, MessageAPI.DELETE_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.DELETE_SCHEMA, async (msg) => { try { - if (msg.payload) { - const id = msg.payload as string; + if (msg) { + const id = msg as string; const item = await schemaRepository.findOne(id); if (item) { if (item.topicId) { @@ -496,9 +493,9 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis } } const schemes = await schemaRepository.find(); - res.send(new MessageResponse(schemes)); + return new MessageResponse(schemes); } catch (error) { - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -509,16 +506,14 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {Schema} Found or uploaded schema */ - ApiResponse(channel, MessageAPI.IMPORT_SCHEMES_BY_MESSAGES, async (msg, res) => { + ApiResponse(channel, MessageAPI.IMPORT_SCHEMES_BY_MESSAGES, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Invalid import schema parameter')); - return; + if (!msg) { + return new MessageError('Invalid import schema parameter'); } - const { owner, messageIds, topicId } = msg.payload; + const { owner, messageIds, topicId } = msg; if (!owner || !messageIds) { - res.send(new MessageError('Invalid import schema parameter')); - return; + return new MessageError('Invalid import schema parameter'); } const files: ISchema[] = []; @@ -529,11 +524,11 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis } const schemesMap = await importSchemaByFiles(owner, files, topicId); - res.send(new MessageResponse(schemesMap)); + return new MessageResponse(schemesMap); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -544,24 +539,22 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {Schema} Found or uploaded schema */ - ApiResponse(channel, MessageAPI.IMPORT_SCHEMES_BY_FILE, async (msg, res) => { + ApiResponse(channel, MessageAPI.IMPORT_SCHEMES_BY_FILE, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Invalid import schema parameter')); - return; + if (!msg) { + return new MessageError('Invalid import schema parameter'); } - const { owner, files, topicId } = msg.payload; + const { owner, files, topicId } = msg; if (!owner || !files) { - res.send(new MessageError('Invalid import schema parameter')); - return; + return new MessageError('Invalid import schema parameter'); } const schemesMap = await importSchemaByFiles(owner, files, topicId); - res.send(new MessageResponse(schemesMap)); + return new MessageResponse(schemesMap); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -572,16 +565,14 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {Schema} Found or uploaded schema */ - ApiResponse(channel, MessageAPI.PREVIEW_SCHEMA, async (msg, res) => { + ApiResponse(channel, MessageAPI.PREVIEW_SCHEMA, async (msg) => { try { - if (!msg.payload) { - res.send(new MessageError('Invalid preview schema parameters')); - return; + if (!msg) { + return new MessageError('Invalid preview schema parameters'); } - const { messageIds } = msg.payload as { messageIds: string[] }; + const { messageIds } = msg as { messageIds: string[] }; if (!messageIds) { - res.send(new MessageError('Invalid preview schema parameters')); - return; + return new MessageError('Invalid preview schema parameters'); } const result = []; for (let i = 0; i < messageIds.length; i++) { @@ -624,11 +615,11 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis schema.newVersions = newVersions.reverse(); } } - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); @@ -640,9 +631,9 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis * * @returns {any} - Response result */ - ApiResponse(channel, MessageAPI.EXPORT_SCHEMES, async (msg, res) => { + ApiResponse(channel, MessageAPI.EXPORT_SCHEMES, async (msg) => { try { - const ids = msg.payload as string[]; + const ids = msg as string[]; const schemas = await schemaRepository.findByIds(ids); const map: any = {}; const relationships: ISchema[] = []; @@ -664,21 +655,21 @@ export const schemaAPI = async function (channel: any, schemaRepository): Promis } } } - res.send(new MessageResponse(relationships)); + return new MessageResponse(relationships); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - ApiResponse(channel, MessageAPI.INCREMENT_SCHEMA_VERSION, async (msg, res) => { + ApiResponse(channel, MessageAPI.INCREMENT_SCHEMA_VERSION, async (msg) => { try { - const { owner, iri } = msg.payload as { owner: string, iri: string }; + const { owner, iri } = msg as { owner: string, iri: string }; const schema = await incrementSchemaVersion(iri, owner); - res.send(new MessageResponse(schema)); + return new MessageResponse(schema); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); } diff --git a/guardian-service/src/api/token.service.ts b/guardian-service/src/api/token.service.ts index 83a938b1b2..8fde78c556 100644 --- a/guardian-service/src/api/token.service.ts +++ b/guardian-service/src/api/token.service.ts @@ -1,5 +1,4 @@ import { Token } from '@entity/token'; -import { IToken, MessageAPI, MessageError, MessageResponse } from 'interfaces'; import { Logger } from 'logger-helper'; import { MongoRepository } from 'typeorm'; import { KeyType, Wallet } from '@helpers/wallet'; @@ -7,6 +6,9 @@ import { Users } from '@helpers/users'; import { HederaSDKHelper } from '@hedera-modules'; import { ApiResponse } from '@api/api-response'; import { IAuthUser } from '@auth/auth.interface'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { MessageAPI, IToken } from 'interfaces'; +import { PrivateKey } from '@hashgraph/sdk'; function getTokenInfo(info: any, token: any) { const tokenId = token.tokenId; @@ -50,7 +52,7 @@ function getTokenInfo(info: any, token: any) { * @param tokenRepository - table with tokens */ export const tokenAPI = async function ( - channel: any, + channel: MessageBrokerChannel, tokenRepository: MongoRepository ): Promise { /** @@ -60,9 +62,9 @@ export const tokenAPI = async function ( * * @returns {IToken[]} - all tokens */ - ApiResponse(channel, MessageAPI.SET_TOKEN, async (msg, res) => { + ApiResponse(channel, MessageAPI.SET_TOKEN, async (msg) => { try { - if (!msg.payload) { + if (!msg) { throw 'Invalid Params'; } @@ -77,8 +79,8 @@ export const tokenAPI = async function ( tokenName, tokenSymbol, tokenType - } = msg.payload.token; - const owner = msg.payload.owner; + } = msg.token; + const owner = msg.owner; if (!tokenName) { throw 'Invalid Token Name'; @@ -92,14 +94,12 @@ export const tokenAPI = async function ( const root = await users.getHederaAccount(owner); const client = new HederaSDKHelper(root.hederaAccountId, root.hederaAccountKey); - const treasury = await client.newAccount(); - const treasuryId = treasury.id; - const treasuryKey = treasury.key; - const adminKey = enableAdmin ? treasuryKey : null; - const kycKey = enableKYC ? treasuryKey : null; - const freezeKey = enableFreeze ? treasuryKey : null; - const wipeKey = enableWipe ? treasuryKey : null; - const supplyKey = changeSupply ? treasuryKey : null; + const rootHederaAccountKey = PrivateKey.fromString(root.hederaAccountKey); + const adminKey = enableAdmin ? rootHederaAccountKey : null; + const kycKey = enableKYC ? rootHederaAccountKey : null; + const freezeKey = enableFreeze ? rootHederaAccountKey : null; + const wipeKey = enableWipe ? rootHederaAccountKey : null; + const supplyKey = changeSupply ? rootHederaAccountKey : null; const nft = tokenType == 'non-fungible'; const _decimals = nft ? 0 : decimals; const _initialSupply = nft ? 0 : initialSupply; @@ -110,7 +110,10 @@ export const tokenAPI = async function ( _decimals, _initialSupply, '', - treasury, + { + id: root.hederaAccountId, + key: rootHederaAccountKey + }, adminKey, kycKey, freezeKey, @@ -124,7 +127,7 @@ export const tokenAPI = async function ( tokenType, decimals: _decimals, initialSupply: _initialSupply, - adminId: treasuryId ? treasuryId.toString() : null, + adminId: root.hederaAccountId, adminKey: adminKey ? adminKey.toString() : null, kycKey: kycKey ? kycKey.toString() : null, freezeKey: freezeKey ? freezeKey.toString() : null, @@ -132,19 +135,26 @@ export const tokenAPI = async function ( supplyKey: supplyKey ? supplyKey.toString() : null, owner: root.did }); - const result = await tokenRepository.save(tokenObject); - const tokens = await tokenRepository.find(); - res.send(new MessageResponse(tokens)); + await tokenRepository.save(tokenObject); + const tokens = await tokenRepository.find({ + where: { + $or: [ + { owner: { $eq: root.did } }, + { owner: { $exists: false } } + ] + } + }); + return new MessageResponse(tokens); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }) - ApiResponse(channel, MessageAPI.FREEZE_TOKEN, async (msg, res) => { + ApiResponse(channel, MessageAPI.FREEZE_TOKEN, async (msg) => { try { - const { tokenId, username, owner, freeze } = msg.payload; + const { tokenId, username, owner, freeze } = msg; const token = await tokenRepository.findOne({ where: { tokenId: { $eq: tokenId } } }); if (!token) { @@ -171,18 +181,18 @@ export const tokenAPI = async function ( const info = await client.accountInfo(user.hederaAccountId); const result = getTokenInfo(info, { tokenId }); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 400)); + return new MessageError(error.message, 400); } }) - ApiResponse(channel, MessageAPI.KYC_TOKEN, async (msg, res) => { + ApiResponse(channel, MessageAPI.KYC_TOKEN, async (msg) => { try { - const { tokenId, username, owner, grant } = msg.payload; + const { tokenId, username, owner, grant } = msg; const token = await tokenRepository.findOne({ where: { tokenId: { $eq: tokenId } } }); if (!token) { @@ -209,17 +219,17 @@ export const tokenAPI = async function ( const info = await client.accountInfo(user.hederaAccountId); const result = getTokenInfo(info, { tokenId }); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 400)); + return new MessageError(error.message, 400); } }) - ApiResponse(channel, MessageAPI.ASSOCIATE_TOKEN, async (msg, res) => { + ApiResponse(channel, MessageAPI.ASSOCIATE_TOKEN, async (msg) => { try { - const { tokenId, did, associate } = msg.payload; + const { tokenId, did, associate } = msg; const token = await tokenRepository.findOne({ where: { tokenId: { $eq: tokenId } } }); if (!token) { @@ -248,17 +258,17 @@ export const tokenAPI = async function ( status = await client.dissociate(tokenId, userID, userKey); } - res.send(new MessageResponse(status)); + return new MessageResponse(status); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 400)); + return new MessageError(error.message, 400); } }) - ApiResponse(channel, MessageAPI.GET_INFO_TOKEN, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_INFO_TOKEN, async (msg) => { try { - const { tokenId, username, owner } = msg.payload; + const { tokenId, username, owner } = msg; const users = new Users(); const user = await users.getUser(username); @@ -272,8 +282,7 @@ export const tokenAPI = async function ( } if (!user.hederaAccountId) { - res.send(new MessageResponse(getTokenInfo(null, token))); - return; + return new MessageResponse(getTokenInfo(null, token)); } const root = await users.getHederaAccount(owner); @@ -281,19 +290,19 @@ export const tokenAPI = async function ( const info = await client.accountInfo(user.hederaAccountId); const result = getTokenInfo(info, token); - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 400)); + return new MessageError(error.message, 400); } }) - ApiResponse(channel, MessageAPI.GET_ASSOCIATED_TOKENS, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_ASSOCIATED_TOKENS, async (msg) => { try { const wallet = new Wallet(); const users = new Users(); - const { did } = msg.payload; + const { did } = msg; const user = await users.getUserById(did); const userID = user.hederaAccountId; const userDID = user.did; @@ -304,17 +313,17 @@ export const tokenAPI = async function ( } if (!user.hederaAccountId) { - res.send(new MessageResponse([])); - return; + return new MessageResponse([]); + } const client = new HederaSDKHelper(userID, userKey); const info = await client.accountInfo(user.hederaAccountId); - const tokens: any = await tokenRepository.find(user.parent - ? { + const tokens: any = await tokenRepository.find(user.parent + ? { where: { $or: [ - { owner: { $eq: user.parent } }, + { owner: { $eq: user.parent } }, { owner: { $exists: false } } ] } @@ -326,11 +335,11 @@ export const tokenAPI = async function ( for (let i = 0; i < tokens.length; i++) { result.push(getTokenInfo(info, tokens[i])); } - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message, 400)); + return new MessageError(error.message, 400); } }) @@ -343,31 +352,31 @@ export const tokenAPI = async function ( * * @returns {IToken[]} - tokens */ - ApiResponse(channel, MessageAPI.GET_TOKENS, async (msg, res) => { - if (msg.payload) { - if (msg.payload.tokenId) { + ApiResponse(channel, MessageAPI.GET_TOKENS, async (msg) => { + if (msg) { + if (msg.tokenId) { const reqObj: any = { where: {} }; - reqObj.where['tokenId'] = { $eq: msg.payload.tokenId } + reqObj.where['tokenId'] = { $eq: msg.tokenId } const tokens: IToken[] = await tokenRepository.find(reqObj); - res.send(new MessageResponse(tokens)); - return; + return new MessageResponse(tokens); + } - if (msg.payload.ids) { + if (msg.ids) { const reqObj: any = { where: {} }; - reqObj.where['tokenId'] = { $in: msg.payload.ids } + reqObj.where['tokenId'] = { $in: msg.ids } const tokens: IToken[] = await tokenRepository.find(reqObj); - res.send(new MessageResponse(tokens)); - return; + return new MessageResponse(tokens); + } } - res.send(new MessageResponse(await tokenRepository.find({ + return new MessageResponse(await tokenRepository.find({ where: { $or: [ - { owner: { $eq: msg.payload.did } }, + { owner: { $eq: msg.did } }, { owner: { $exists: false } } ] } - }))); + })); }) /** @@ -377,9 +386,9 @@ export const tokenAPI = async function ( * * @returns {IToken[]} - all tokens */ - ApiResponse(channel, MessageAPI.IMPORT_TOKENS, async (msg, res) => { + ApiResponse(channel, MessageAPI.IMPORT_TOKENS, async (msg) => { try { - let items: IToken[] = msg.payload; + let items: IToken[] = msg; if (!Array.isArray(items)) { items = [items]; } @@ -392,11 +401,11 @@ export const tokenAPI = async function ( const tokenObject = tokenRepository.create(items); const result = await tokenRepository.save(tokenObject); const tokens = await tokenRepository.find(); - res.send(new MessageResponse(tokens)); + return new MessageResponse(tokens); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }) } \ No newline at end of file diff --git a/guardian-service/src/api/trust-chain.service.ts b/guardian-service/src/api/trust-chain.service.ts index bbd9d36176..2b53bc9fda 100644 --- a/guardian-service/src/api/trust-chain.service.ts +++ b/guardian-service/src/api/trust-chain.service.ts @@ -4,8 +4,6 @@ import { VpDocument } from '@entity/vp-document'; import { IChainItem, MessageAPI, - MessageError, - MessageResponse, SchemaEntity } from 'interfaces'; import { Logger } from 'logger-helper'; @@ -15,6 +13,7 @@ import { VpDocument as HVpDocument } from '@hedera-modules'; import { ApiResponse } from '@api/api-response'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; function getField(vcDocument: VcDocument | VpDocument, name: string): any { if ( @@ -53,7 +52,7 @@ function checkPolicy(vcDocument: VcDocument, policyId: string) { * @param vpDocumentRepository - table with VP Documents */ export const trustChainAPI = async function ( - channel: any, + channel: MessageBrokerChannel, didDocumentRepository: MongoRepository, vcDocumentRepository: MongoRepository, vpDocumentRepository: MongoRepository @@ -213,9 +212,9 @@ export const trustChainAPI = async function ( * * @returns {IChainItem[]} - trust chain */ - ApiResponse(channel, MessageAPI.GET_CHAIN, async (msg, res) => { + ApiResponse(channel, MessageAPI.GET_CHAIN, async (msg) => { try { - const hash = msg.payload; + const hash = msg; const chain: IChainItem[] = []; let root: VcDocument | VpDocument; @@ -224,8 +223,7 @@ export const trustChainAPI = async function ( const policyId = root.policyId; await getParents(chain, root, {}, policyId); await getPolicyInfo(chain, policyId); - res.send(new MessageResponse(chain)); - return; + return new MessageResponse(chain); } root = await vpDocumentRepository.findOne({ hash: hash }); @@ -247,8 +245,7 @@ export const trustChainAPI = async function ( const vc = await vcDocumentRepository.findOne({ hash: hashVc }); await getParents(chain, vc, {}, policyId); await getPolicyInfo(chain, policyId); - res.send(new MessageResponse(chain)); - return; + return new MessageResponse(chain); } root = await vpDocumentRepository.findOne({ where: { 'document.id': { $eq: hash } } }); @@ -270,16 +267,15 @@ export const trustChainAPI = async function ( const vc = await vcDocumentRepository.findOne({ hash: hashVc }); await getParents(chain, vc, {}, policyId); await getPolicyInfo(chain, policyId); - res.send(new MessageResponse(chain)); - return; + return new MessageResponse(chain); } await getPolicyInfo(chain, null); - res.send(new MessageResponse(chain)); + return new MessageResponse(chain); } catch (error) { new Logger().error(error.message, ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); } diff --git a/guardian-service/src/app.ts b/guardian-service/src/app.ts index 4a06ba6d28..514873e9a2 100644 --- a/guardian-service/src/app.ts +++ b/guardian-service/src/app.ts @@ -1,4 +1,3 @@ -import FastMQ from 'fastmq' import { createConnection } from 'typeorm'; import { approveAPI } from '@api/approve.service'; import { configAPI } from '@api/config.service'; @@ -21,10 +20,11 @@ import { Wallet } from '@helpers/wallet'; import { Users } from '@helpers/users'; import { Settings } from '@entity/settings'; import { Logger } from 'logger-helper'; -import { ApplicationState, ApplicationStates } from 'interfaces'; import { Topic } from '@entity/topic'; import { PolicyEngineService } from '@policy-engine/policy-engine.service'; import { Policy } from '@entity/policy'; +import { MessageBrokerChannel, ApplicationState } from 'common'; +import { ApplicationStates } from 'interfaces'; Promise.all([ createConnection({ @@ -41,10 +41,10 @@ Promise.all([ entitiesDir: 'dist/entity' } }), - FastMQ.Client.connect(process.env.SERVICE_CHANNEL, 7500, process.env.MQ_ADDRESS) + MessageBrokerChannel.connect("GUARDIANS_SERVICE") ]).then(async values => { - const [db, channel] = values; - + const [db, cn] = values; + const channel = new MessageBrokerChannel(cn, "guardians"); const state = new ApplicationState('GUARDIANS_SERVICE'); state.setChannel(channel); state.updateState(ApplicationStates.STARTED); diff --git a/guardian-service/src/entity/aggregateDocuments.ts b/guardian-service/src/entity/aggregateDocuments.ts index aa287f7ad9..7cce0f1a83 100644 --- a/guardian-service/src/entity/aggregateDocuments.ts +++ b/guardian-service/src/entity/aggregateDocuments.ts @@ -1,3 +1,4 @@ +import { DocumentSignature, DocumentStatus } from 'interfaces'; import {Column, Entity, ObjectIdColumn} from 'typeorm'; /** @@ -8,9 +9,51 @@ export class AggregateVC { @ObjectIdColumn() id: string; + @Column() + owner: string; + + @Column() + assign: string; + + @Column() + hash: string; + @Column() document: any; @Column() - owner: string; + hederaStatus: DocumentStatus; + + @Column() + signature: DocumentSignature; + + @Column() + processingStatus: string; + + @Column() + type: string; + + @Column() + policyId: string; + + @Column() + blockId: string; + + @Column() + tag: string; + + @Column() + option: any; + + @Column() + schema: string; + + @Column() + messageId: string; + + @Column() + topicId: string; + + @Column() + relationships: string[]; } diff --git a/guardian-service/src/entity/policy.ts b/guardian-service/src/entity/policy.ts index c5cddd17d0..4b8775c44a 100644 --- a/guardian-service/src/entity/policy.ts +++ b/guardian-service/src/entity/policy.ts @@ -1,5 +1,5 @@ -import {BeforeInsert, Column, CreateDateColumn, Entity, ObjectIdColumn} from 'typeorm'; import { ModelHelper } from 'interfaces'; +import { BeforeInsert, Column, CreateDateColumn, Entity, ObjectIdColumn } from 'typeorm'; /** * Policy collection @@ -50,7 +50,7 @@ export class Policy { @Column() topicId: string; - + @Column() instanceTopicId: string; @@ -58,10 +58,10 @@ export class Policy { unique: true }) policyTag: string; - + @Column() messageId: string; - + @CreateDateColumn() createDate: Date; diff --git a/guardian-service/src/entity/schema.ts b/guardian-service/src/entity/schema.ts index 5151ab7627..2b8393aa9d 100644 --- a/guardian-service/src/entity/schema.ts +++ b/guardian-service/src/entity/schema.ts @@ -1,4 +1,4 @@ -import { ISchema, ModelHelper, SchemaEntity, SchemaStatus, SchemaCategory, ISchemaDocument } from 'interfaces'; +import { ISchema, ISchemaDocument, SchemaCategory, SchemaEntity, SchemaStatus, ModelHelper } from 'interfaces'; import { AfterLoad, BeforeInsert, BeforeUpdate, Column, CreateDateColumn, Entity, Index, ObjectIdColumn } from 'typeorm'; @Entity() @@ -44,7 +44,7 @@ export class Schema implements ISchema { @Column() topicId: string; - + @Column() messageId: string; @@ -72,7 +72,7 @@ export class Schema implements ISchema { this.readonly = !!this.readonly; this.uuid = this.uuid || ModelHelper.randomUUID(); this.iri = this.iri || `${this.uuid}`; - if(this.status == SchemaStatus.DRAFT) { + if (this.status == SchemaStatus.DRAFT) { this.messageId = null; } } diff --git a/guardian-service/src/hedera-modules/hedera-sdk-helper.ts b/guardian-service/src/hedera-modules/hedera-sdk-helper.ts index a75f134888..f1f39b2296 100644 --- a/guardian-service/src/hedera-modules/hedera-sdk-helper.ts +++ b/guardian-service/src/hedera-modules/hedera-sdk-helper.ts @@ -74,7 +74,7 @@ export class HederaSDKHelper { initialSupply: number, tokenMemo: string, treasury: { - id: AccountId; + id: AccountId | string; key: PrivateKey; }, adminKey: PrivateKey, diff --git a/guardian-service/src/hedera-modules/message/did-message.ts b/guardian-service/src/hedera-modules/message/did-message.ts index 23c4eaa4e3..8b419f403c 100644 --- a/guardian-service/src/hedera-modules/message/did-message.ts +++ b/guardian-service/src/hedera-modules/message/did-message.ts @@ -43,16 +43,26 @@ export class DIDMessage extends Message { } public loadDocuments(documents: string[]): DIDMessage { - this.document = JSON.parse(documents[0]); + if (documents && Array.isArray(documents)) { + this.document = JSON.parse(documents[0]); + } return this; } public static fromMessage(message: string): DIDMessage { + if (!message) { + throw new Error('JSON Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: DidMessageBody): DIDMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + const message = new DIDMessage(json.action); message._id = json.id; message._status = json.status; diff --git a/guardian-service/src/hedera-modules/message/policy-message.ts b/guardian-service/src/hedera-modules/message/policy-message.ts index ae8ce12f5b..49c16d16a7 100644 --- a/guardian-service/src/hedera-modules/message/policy-message.ts +++ b/guardian-service/src/hedera-modules/message/policy-message.ts @@ -78,11 +78,19 @@ export class PolicyMessage extends Message { } public static fromMessage(message: string): PolicyMessage { + if (!message) { + throw new Error('Message Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: PolicyMessageBody): PolicyMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + if (json.type != MessageType.Policy && json.type != MessageType.InstancePolicy) { throw 'Invalid message type' } diff --git a/guardian-service/src/hedera-modules/message/schema-message.ts b/guardian-service/src/hedera-modules/message/schema-message.ts index 2a61b563ea..63e07498c8 100644 --- a/guardian-service/src/hedera-modules/message/schema-message.ts +++ b/guardian-service/src/hedera-modules/message/schema-message.ts @@ -73,16 +73,26 @@ export class SchemaMessage extends Message { } public loadDocuments(documents: string[]): SchemaMessage { - this.documents = documents.map(e => JSON.parse(e)); + if (documents && Array.isArray(documents)) { + this.documents = documents.map(e => JSON.parse(e)); + } return this; } public static fromMessage(message: string): SchemaMessage { + if (!message) { + throw new Error('Message Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: SchemaMessageBody): SchemaMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + const message = new SchemaMessage(json.action); message._id = json.id; message._status = json.status; diff --git a/guardian-service/src/hedera-modules/message/topic-message.ts b/guardian-service/src/hedera-modules/message/topic-message.ts index eae572cd94..49a954ead1 100644 --- a/guardian-service/src/hedera-modules/message/topic-message.ts +++ b/guardian-service/src/hedera-modules/message/topic-message.ts @@ -60,11 +60,19 @@ export class TopicMessage extends Message { } public static fromMessage(message: string): TopicMessage { + if (!message) { + throw new Error('Message Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: TopicMessageBody): TopicMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + if (json.type != MessageType.Topic) { throw 'Invalid message type' } diff --git a/guardian-service/src/hedera-modules/message/vc-message.ts b/guardian-service/src/hedera-modules/message/vc-message.ts index 0d1d2dedbf..a8d9fef7e2 100644 --- a/guardian-service/src/hedera-modules/message/vc-message.ts +++ b/guardian-service/src/hedera-modules/message/vc-message.ts @@ -56,11 +56,19 @@ export class VCMessage extends Message { } public static fromMessage(message: string): VCMessage { + if (!message) { + throw new Error('Message Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: VcMessageBody): VCMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + const message = new VCMessage(json.action); message._id = json.id; message._status = json.status; diff --git a/guardian-service/src/hedera-modules/message/vp-message.ts b/guardian-service/src/hedera-modules/message/vp-message.ts index b92029f8ea..e391e87185 100644 --- a/guardian-service/src/hedera-modules/message/vp-message.ts +++ b/guardian-service/src/hedera-modules/message/vp-message.ts @@ -56,11 +56,19 @@ export class VPMessage extends Message { } public static fromMessage(message: string): VPMessage { + if (!message) { + throw new Error('Message Object is empty'); + } + const json = JSON.parse(message); return this.fromMessageObject(json); } public static fromMessageObject(json: VpMessageBody): VPMessage { + if (!json) { + throw new Error('JSON Object is empty'); + } + const message = new VPMessage(json.action); message._id = json.id; message._status = json.status; diff --git a/guardian-service/src/hedera-modules/vcjs/did-document.ts b/guardian-service/src/hedera-modules/vcjs/did-document.ts index 0e53f64111..aaad723e1d 100644 --- a/guardian-service/src/hedera-modules/vcjs/did-document.ts +++ b/guardian-service/src/hedera-modules/vcjs/did-document.ts @@ -64,6 +64,10 @@ export class DidRootKey { } public static fromJsonTree(json: any): DidRootKey { + if (!json) { + throw new Error('JSON Object is empty'); + } + const result = new DidRootKey(); result.id = json.id; result.type = json.type; @@ -73,6 +77,10 @@ export class DidRootKey { } public static fromJson(json: string): DidRootKey { + if (!json) { + throw new Error('JSON Object is empty'); + } + return DidRootKey.fromJsonTree(JSON.parse(json)); } @@ -363,6 +371,9 @@ export class DIDDocument { if (!did) { throw new Error("DID string cannot be null"); } + if (!didRootKey) { + throw new Error("DID Root Key is empty"); + } const mainParts = did.split(DIDDocument.DID_PARAMETER_SEPARATOR); const didParts = mainParts[0].split(DIDDocument.DID_METHOD_SEPARATOR); const prefix = didParts[0]; @@ -392,12 +403,10 @@ export class DIDDocument { const result = new DIDDocument(); result.privateKey = null; - if (didRootKey) { - if (typeof didRootKey === 'string') { - result.publicKey = PublicKey.fromString(topicId); - } else { - result.publicKey = didRootKey; - } + if (typeof didRootKey === 'string') { + result.publicKey = PublicKey.fromString(didRootKey); + } else { + result.publicKey = didRootKey; } if (topicId) { if (typeof topicId === 'string') { diff --git a/guardian-service/src/hedera-modules/vcjs/issuer.ts b/guardian-service/src/hedera-modules/vcjs/issuer.ts index 13ef08a154..3f62359ab8 100644 --- a/guardian-service/src/hedera-modules/vcjs/issuer.ts +++ b/guardian-service/src/hedera-modules/vcjs/issuer.ts @@ -30,6 +30,10 @@ export class Issuer { } public static fromJsonTree(root: any): Issuer { + if (!root) { + throw new Error("JSON Object is empty"); + } + let id: string, name: string; if (typeof root == "string") { id = root; diff --git a/guardian-service/src/hedera-modules/vcjs/vc-document.ts b/guardian-service/src/hedera-modules/vcjs/vc-document.ts index f822eafc12..534e29d882 100644 --- a/guardian-service/src/hedera-modules/vcjs/vc-document.ts +++ b/guardian-service/src/hedera-modules/vcjs/vc-document.ts @@ -167,6 +167,10 @@ export class VcDocument { public static fromJsonTree(json: IVC): VcDocument { + if (!json) { + throw new Error('JSON Object is empty'); + } + const result = new VcDocument(); if (json[VcDocument.ID]) diff --git a/guardian-service/src/hedera-modules/vcjs/vc-subject.ts b/guardian-service/src/hedera-modules/vcjs/vc-subject.ts index 25c0584c2e..9fd2ca9907 100644 --- a/guardian-service/src/hedera-modules/vcjs/vc-subject.ts +++ b/guardian-service/src/hedera-modules/vcjs/vc-subject.ts @@ -83,6 +83,11 @@ export class VcSubject { return json; } + public getFields(): any { + const json = Object.assign({}, this.document); + return json; + } + public static fromJson(json: string): VcSubject { let result: VcSubject; try { @@ -99,6 +104,10 @@ export class VcSubject { } public static create(subject: any, schema?: string): VcSubject { + if (!subject) { + throw new Error('Subject is empty'); + } + const result = new VcSubject(); result.id = subject[VcSubject.CREDENTIAL_ID]; diff --git a/guardian-service/src/hedera-modules/vcjs/vp-document.ts b/guardian-service/src/hedera-modules/vcjs/vp-document.ts index 93544e9f8e..790fbd99b0 100644 --- a/guardian-service/src/hedera-modules/vcjs/vp-document.ts +++ b/guardian-service/src/hedera-modules/vcjs/vp-document.ts @@ -163,6 +163,10 @@ export class VpDocument { } public static fromJsonTree(json: IVP): VpDocument { + if (!json) { + throw new Error('JSON Object is empty'); + } + const result = new VpDocument(); if (json[VpDocument.ID]) result.id = json[VpDocument.ID]; diff --git a/guardian-service/src/helpers/ipfs.ts b/guardian-service/src/helpers/ipfs.ts index 67a18ed72a..43d849b36b 100644 --- a/guardian-service/src/helpers/ipfs.ts +++ b/guardian-service/src/helpers/ipfs.ts @@ -1,24 +1,25 @@ -import { MessageAPI } from "interfaces"; +import { MessageBrokerChannel } from "common"; +import { MessageAPI, IGetFileMessage, IFileResponse, IAddFileMessage } from "interfaces"; /** * IPFS service */ export class IPFS { - private static channel: any; + private static channel: MessageBrokerChannel; private static readonly target: string = 'ipfs-client'; /** * Register channel * @param channel */ - public static setChannel(channel: any): any { + public static setChannel(channel: MessageBrokerChannel) { this.channel = channel; } /** * Get channel */ - public static getChannel(): any { + public static getChannel(): MessageBrokerChannel { return this.channel; } @@ -29,7 +30,7 @@ export class IPFS { * @returns {string} - hash */ public static async addFile(file: ArrayBuffer): Promise<{ cid: string, url: string }> { - const res = (await this.channel.request(this.target, MessageAPI.IPFS_ADD_FILE, file, 'raw')).payload; + const res = await this.channel.request([this.target, MessageAPI.IPFS_ADD_FILE].join('.'), { content: Buffer.from(file).toString('base64') }); if (!res) { throw new Error('Invalid response'); } @@ -46,7 +47,7 @@ export class IPFS { * @returns File */ public static async getFile(cid: string, responseType: 'json' | 'raw' | 'str'): Promise { - const res = (await this.channel.request(this.target, MessageAPI.IPFS_GET_FILE, { cid, responseType }, 'json')).payload; + const res = (await this.channel.request([this.target, MessageAPI.IPFS_GET_FILE].join('.'), { cid, responseType })); if (!res) { throw new Error('Invalid response'); } diff --git a/guardian-service/src/helpers/serviceRequestsBase.ts b/guardian-service/src/helpers/serviceRequestsBase.ts index 22df69a869..0b131106fc 100644 --- a/guardian-service/src/helpers/serviceRequestsBase.ts +++ b/guardian-service/src/helpers/serviceRequestsBase.ts @@ -1,21 +1,21 @@ -import { IMessageResponse } from 'interfaces'; +import { MessageBrokerChannel } from "common"; export abstract class ServiceRequestsBase { - protected channel: any; + protected channel: MessageBrokerChannel; abstract readonly target: string; /** * Register channel * @param channel */ - public setChannel(channel: any): any { + public setChannel(channel: MessageBrokerChannel) { this.channel = channel; } /** * Get channel */ - public getChannel(): any { + public getChannel(): MessageBrokerChannel { return this.channel; } @@ -25,17 +25,16 @@ export abstract class ServiceRequestsBase { * @param params * @param type */ - public async request(entity: string, params?: any, type?: string): Promise { + public async request(entity: string, params?: any, type?: string): Promise { try { - const response = await this.channel.request(this.target, entity, params, type); + const response = await this.channel.request(`${this.target}.${entity}`, params); if (!response) { throw 'Server is not available'; } - const payload: IMessageResponse = response.payload; - if (payload.error) { - throw payload.error; + if (response.error) { + throw response.error; } - return payload.body; + return response.body; } catch (e) { throw new Error(`Guardian (${entity}) send: ` + e); } diff --git a/guardian-service/src/helpers/wallet.ts b/guardian-service/src/helpers/wallet.ts index 56faab743b..228424e4ff 100644 --- a/guardian-service/src/helpers/wallet.ts +++ b/guardian-service/src/helpers/wallet.ts @@ -1,6 +1,6 @@ -import {Singleton} from '@helpers/decorators/singleton'; +import { Singleton } from '@helpers/decorators/singleton'; import { ServiceRequestsBase } from '@helpers/serviceRequestsBase'; -import { WalletEvents } from 'interfaces'; +import { WalletEvents, IGetKeyResponse } from 'interfaces'; export enum KeyType { ID = 'ID', @@ -21,7 +21,7 @@ export class Wallet extends ServiceRequestsBase { * @param key */ public async getKey(token: string, type: KeyType, key: string): Promise { - const wallet = await this.request(WalletEvents.GET_KEY, {token, type, key}); + const wallet = await this.request(WalletEvents.GET_KEY, { token, type, key }); return wallet.key; } @@ -33,6 +33,6 @@ export class Wallet extends ServiceRequestsBase { * @param value */ public async setKey(token: string, type: string, key: string, value: string) { - await this.request(WalletEvents.SET_KEY, {token, type, key, value}); + await this.request(WalletEvents.SET_KEY, { token, type, key, value }); } } diff --git a/guardian-service/src/policy-engine/block-tree-generator.ts b/guardian-service/src/policy-engine/block-tree-generator.ts index 1a51610637..bbf069bd55 100644 --- a/guardian-service/src/policy-engine/block-tree-generator.ts +++ b/guardian-service/src/policy-engine/block-tree-generator.ts @@ -88,6 +88,7 @@ export class BlockTreeGenerator { return blockInstance; } + new Logger().info('Start policy', ['GUARDIAN_SERVICE', policy.name, policyId.toString()]); const model = await BuildInstances(configObject); if (!skipRegistration) { this.models.set(policy.id.toString(), model as any); diff --git a/guardian-service/src/policy-engine/blocks/aggregate-block.ts b/guardian-service/src/policy-engine/blocks/aggregate-block.ts index 13d4099c68..bfba698cd2 100644 --- a/guardian-service/src/policy-engine/blocks/aggregate-block.ts +++ b/guardian-service/src/policy-engine/blocks/aggregate-block.ts @@ -1,23 +1,16 @@ import { BasicBlock } from '@policy-engine/helpers/decorators'; -import * as mathjs from 'mathjs'; -import { BlockActionError } from '@policy-engine/errors'; import { getMongoRepository } from 'typeorm'; import { AggregateVC } from '@entity/aggregateDocuments'; import { PolicyValidationResultsContainer } from '@policy-engine/policy-validation-results-container'; import { PolicyComponentsUtils } from '../policy-components-utils'; import { IAuthUser } from '@auth/auth.interface'; import { VcDocument } from '@hedera-modules'; -import { Token } from '@entity/token'; - -function evaluate(formula: string, scope: any) { - return (function (formula: string, scope: any) { - try { - return this.evaluate(formula, scope); - } catch (error) { - return 'Incorrect formula'; - } - }).call(mathjs, formula, scope); -} +import { AnyBlockType } from '@policy-engine/policy-engine.interface'; +import { Users } from '@helpers/users'; +import { Inject } from '@helpers/decorators/inject'; +import { DocumentSignature, DocumentStatus } from 'interfaces'; +import { PolicyUtils } from '@policy-engine/helpers/utils'; +import { PolicyEvent } from '@policy-engine/interfaces/policy-event'; /** * Aggregate block @@ -27,70 +20,193 @@ function evaluate(formula: string, scope: any) { commonBlock: true }) export class AggregateBlock { - private getScope(item: VcDocument): any { - return item.getCredentialSubject(0).toJsonTree(); - } + @Inject() + private users: Users; - private aggregate(rule, vcs: VcDocument[]) { - let amount = 0; - for (let i = 0; i < vcs.length; i++) { - const element = vcs[i]; - const scope = this.getScope(element); - const value = parseFloat(evaluate(rule, scope)); - amount += value; + start() { + const ref = PolicyComponentsUtils.GetBlockRef(this); + if (ref.options.aggregateType == 'period') { + PolicyComponentsUtils.RegisterEvent( + ref.policyId, ref.options.timer, 'TimerEvent', this.tickCron.bind(this) + ); } - return amount; } - async runAction(data: any, user: IAuthUser) { + private async tickCron(event: PolicyEvent) { const ref = PolicyComponentsUtils.GetBlockRef(this); - const { - tokenId, - rule, - threshold - } = ref.options; - - const token = await getMongoRepository(Token).findOne({ tokenId }); - if (!token) { - throw new BlockActionError('Bad token id', ref.blockType, ref.uuid); + + const users = event.data || []; + + ref.log(`tick scheduler, ${users.length}`); + + const repository = getMongoRepository(AggregateVC); + const rawEntities = await repository.find({ + policyId: ref.policyId, + blockId: ref.uuid + }); + + const map = new Map(); + const removeMsp:AggregateVC[] = []; + for (let did of users) { + map.set(did, []); + } + for (let element of rawEntities) { + const owner = element.owner; + if (map.has(owner)) { + map.get(owner).push(element); + } else { + removeMsp.push(element); + } + } + + if(removeMsp.length) { + await repository.remove(removeMsp); } - const doc = data.data; + for (let did of users) { + const user = await this.users.getUserById(did); + const documents = map.get(did); + if(documents.length) { + await repository.remove(documents); + } + if(documents.length || ref.options.emptyData) { + await ref.runNext(user, { data: documents }); + } + } + } + + private expressions(expressions: any[], doc: AggregateVC): any { + const result: any = {}; + if (!expressions || !expressions.length) { + return result; + } + const element = VcDocument.fromJsonTree(doc.document); + const scope = PolicyUtils.getVCScope(element); + for (let i = 0; i < expressions.length; i++) { + const expression = expressions[i]; + result[expression.name] = parseFloat(PolicyUtils.evaluate(expression.value, scope)); + } + return result; + } + + private aggregateScope(scopes: any[]): any { + const result: any = {}; + if (!scopes || !scopes.length) { + return result; + } + const keys = Object.keys(scopes[0]); + for (let key of keys) { + result[key] = []; + } + for (let scope of scopes) { + for (let key of keys) { + result[key].push(scope[key]); + } + } + return result; + } + + private async tickAggregate(ref: AnyBlockType, owner: string) { + const { expressions, condition } = ref.options; + + const repository = getMongoRepository(AggregateVC); + const rawEntities = await repository.find({ + owner: owner, + policyId: ref.policyId, + blockId: ref.uuid + }); + + const scopes: any[] = []; + for (let doc of rawEntities) { + const scope = this.expressions(expressions, doc); + scopes.push(scope); + } + const scope = this.aggregateScope(scopes); + const result = PolicyUtils.evaluate(condition, scope); + + ref.log(`tick aggregate: ${owner}, ${result}, ${JSON.stringify(scope)}`); + + if (result === true) { + const user = await this.users.getUserById(owner); + await repository.remove(rawEntities); + await ref.runNext(user, { data: rawEntities }); + } + } + + async saveDocuments(ref: AnyBlockType, doc: any): Promise { const vc = VcDocument.fromJsonTree(doc.document); - const repository = getMongoRepository(AggregateVC) + const repository = getMongoRepository(AggregateVC); const newVC = repository.create({ + policyId: ref.policyId, + blockId: ref.uuid, + tag: doc.tag, + type: doc.type, owner: doc.owner, + assign: doc.assign, + option: doc.option, + schema: doc.schema, + hederaStatus: doc.hederaStatus || DocumentStatus.NEW, + signature: doc.signature || DocumentSignature.NEW, + messageId: doc.messageId || null, + topicId: doc.topicId || null, + relationships: doc.relationships || [], + hash: vc.toCredentialHash(), document: vc.toJsonTree() }); await repository.save(newVC); + } - const rawEntities = await repository.find({ - owner: doc.owner - }); - const forAggregate = rawEntities.map(e => VcDocument.fromJsonTree(e.document)); - const amount = this.aggregate(rule, forAggregate); + async runAction(state: any, user: IAuthUser) { + const ref = PolicyComponentsUtils.GetBlockRef(this); + const { aggregateType } = ref.options; - if (amount >= threshold) { - await repository.remove(rawEntities); - await ref.runNext(null, { data: rawEntities }); + const docs: any | any[] = state.data; + let owner: string = null; + if (Array.isArray(docs)) { + for (let doc of docs) { + owner = doc.owner; + await this.saveDocuments(ref, doc); + } + } else { + owner = docs.owner; + await this.saveDocuments(ref, docs); + } + + if (aggregateType == 'cumulative') { + this.tickAggregate(ref, owner).then(); } } public async validate(resultsContainer: PolicyValidationResultsContainer): Promise { const ref = PolicyComponentsUtils.GetBlockRef(this); try { - // Test rule options - if (!ref.options.rule) { - resultsContainer.addBlockError(ref.uuid, 'Option "rule" does not set'); - } else if (typeof ref.options.rule !== 'string') { - resultsContainer.addBlockError(ref.uuid, 'Option "rule" must be a string'); - } - - // Test threshold options - if (!ref.options.threshold) { - resultsContainer.addBlockError(ref.uuid, 'Option "threshold" does not set'); - } else if (typeof ref.options.threshold !== 'string') { - resultsContainer.addBlockError(ref.uuid, 'Option "threshold" must be a string'); + if (ref.options.aggregateType == 'period') { + if (!ref.options.timer && !resultsContainer.isTagExist(ref.options.timer)) { + resultsContainer.addBlockError(ref.uuid, `Tag "${ref.options.timer}" does not exist`); + } + } else if (ref.options.aggregateType == 'cumulative') { + let variables: any = {}; + if (ref.options.expressions) { + for (let i = 0; i < ref.options.expressions.length; i++) { + const expression = ref.options.expressions[i]; + variables[expression.name] = true; + } + } + if (!ref.options.condition) { + resultsContainer.addBlockError(ref.uuid, 'Option "condition" does not set'); + } else if (typeof ref.options.condition !== 'string') { + resultsContainer.addBlockError(ref.uuid, 'Option "condition" must be a string'); + } else { + const vars = PolicyUtils.variables(ref.options.condition); + for (let i = 0; i < vars.length; i++) { + const varName = vars[i]; + if (!variables[varName]) { + resultsContainer.addBlockError(ref.uuid, `Variable ${varName} not defined`); + } + } + } + } else { + resultsContainer.addBlockError(ref.uuid, 'Option "aggregateType" must be one of period, cumulative'); } } catch (error) { resultsContainer.addBlockError(ref.uuid, `Unhandled exception ${error.message}`); diff --git a/guardian-service/src/policy-engine/blocks/calculate-block.ts b/guardian-service/src/policy-engine/blocks/calculate-block.ts index b211a1470b..19eb489f9e 100644 --- a/guardian-service/src/policy-engine/blocks/calculate-block.ts +++ b/guardian-service/src/policy-engine/blocks/calculate-block.ts @@ -10,6 +10,7 @@ import { VcDocument } from '@hedera-modules'; import { VcHelper } from '@helpers/vcHelper'; import { getMongoRepository } from 'typeorm'; import { Schema as SchemaCollection } from '@entity/schema'; +import { VcDocument as VcDocumentCollection } from '@entity/vc-document'; import { Inject } from '@helpers/decorators/inject'; import { Users } from '@helpers/users'; @@ -21,93 +22,128 @@ export class CalculateContainerBlock { @Inject() private users: Users; - async calculate(document: any) { - const ref = PolicyComponentsUtils.GetBlockRef(this); - if (document.signature === DocumentSignature.INVALID) { - throw new BlockActionError('Invalid VC proof', ref.blockType, ref.uuid); - } - - const VC = VcDocument.fromJsonTree(document.document); - const json = VC.getCredentialSubject(0).toJsonTree(); - + private async calculate(documents: any | any[], ref: IPolicyCalculateBlock): Promise { + const fields = ref.options.inputFields; let scope = {}; - if (ref.options.inputFields) { - for (let i = 0; i < ref.options.inputFields.length; i++) { - const field = ref.options.inputFields[i]; - scope[field.value] = json[field.name]; + if (fields) { + if (Array.isArray(documents)) { + for (let field of fields) { + const value = []; + for (let json of documents) { + value.push(json[field.name]); + } + scope[field.value] = value; + } + } else { + for (let field of fields) { + scope[field.value] = documents[field.name]; + } } } - const addons = ref.getAddons(); for (let i = 0; i < addons.length; i++) { const addon = addons[i]; scope = await addon.run(scope); } - let newJson: any = {}; if (ref.options.outputFields) { - for (let i = 0; i < ref.options.outputFields.length; i++) { - const field = ref.options.outputFields[i]; + for (let field of ref.options.outputFields) { if (scope[field.value]) { newJson[field.name] = scope[field.value]; } } } - newJson.id = json.id; + return newJson; + } - const outputSchema = await getMongoRepository(SchemaCollection).findOne({ - iri: ref.options.outputSchema - }); - const vcSubject = { - ...SchemaHelper.getContext(outputSchema), - ...newJson + private async process(documents: any | any[], ref: IPolicyCalculateBlock): Promise { + const isArray = Array.isArray(documents); + if (!documents || (isArray && !documents.length)) { + throw new BlockActionError('Invalid VC', ref.blockType, ref.uuid); + } + + // <-- aggregate + const relationships = []; + const owner = isArray ? documents[0].owner : documents.owner; + let vcs: VcDocument | VcDocument[]; + let json: any | any[]; + if (isArray) { + vcs = []; + json = []; + for (let doc of documents) { + const vc = VcDocument.fromJsonTree(doc.document); + vcs.push(vc); + json.push(vc.getCredentialSubject(0).toJsonTree()); + if (doc.messageId) { + relationships.push(doc.messageId); + } + } + } else { + vcs = VcDocument.fromJsonTree(documents.document); + json = vcs.getCredentialSubject(0).toJsonTree(); + if (documents.messageId) { + relationships.push(documents.messageId); + } } + const vcId = isArray ? json[0].id : json.id; + const vcReference = isArray ? json[0].ref : json.ref; + // --> + + const newJson = await this.calculate(json, ref); - if (json.ref) { - vcSubject.ref = json.ref; + // <-- new vc + const outputSchema = await getMongoRepository(SchemaCollection).findOne({ iri: ref.options.outputSchema }); + const vcSubject: any = { + ...SchemaHelper.getContext(outputSchema), + ...newJson } - if (json.policyId) { - vcSubject.policyId = json.policyId; + vcSubject.policyId = ref.policyId; + vcSubject.id = vcId; + if (vcReference) { + vcSubject.ref = vcReference; } const root = await this.users.getHederaAccount(ref.policyOwner); - const VCHelper = new VcHelper(); - const newVC = await VCHelper.createVC( - root.did, - root.hederaAccountKey, - vcSubject - ); + const newVC = await VCHelper.createVC(root.did, root.hederaAccountKey, vcSubject); const item = { hash: newVC.toCredentialHash(), - owner: document.owner, document: newVC.toJsonTree(), + owner: owner, schema: outputSchema.iri, type: outputSchema.iri, policyId: ref.policyId, tag: ref.tag, messageId: null, topicId: null, - relationships: document.messageId ? [document.messageId] : null + relationships: relationships.length ? relationships : null }; + // --> + return item; } @CatchErrors() public async runAction(state: any, user: IAuthUser) { const ref = PolicyComponentsUtils.GetBlockRef(this); - let document = null; - if (Array.isArray(state.data)) { - document = state.data[0]; + + if (ref.options.inputDocuments == 'separate') { + if (Array.isArray(state.data)) { + const result = []; + for (let doc of state.data) { + const newVC = await this.process(doc, ref); + result.push(newVC) + } + state.data = result; + } else { + state.data = await this.process(state.data, ref); + } } else { - document = state.data; + state.data = await this.process(state.data, ref); } - const newDocument = await this.calculate(document); - state.data = newDocument; await ref.runNext(user, state); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, user); - PolicyComponentsUtils.CallParentContainerCallback(ref, user); - // ref.updateBlock(state, user, ''); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); } public async validate(resultsContainer: PolicyValidationResultsContainer): Promise { diff --git a/guardian-service/src/policy-engine/blocks/custom-logic-block.ts b/guardian-service/src/policy-engine/blocks/custom-logic-block.ts new file mode 100644 index 0000000000..609dc120a4 --- /dev/null +++ b/guardian-service/src/policy-engine/blocks/custom-logic-block.ts @@ -0,0 +1,112 @@ +import { BasicBlock } from '@policy-engine/helpers/decorators'; +import { CatchErrors } from '@policy-engine/helpers/decorators/catch-errors'; +import { IAuthUser } from '@auth/auth.interface'; +import { PolicyComponentsUtils } from '@policy-engine/policy-components-utils'; +import { IPolicyCalculateBlock } from '@policy-engine/policy-engine.interface'; +import { getMongoRepository } from 'typeorm'; +import { Schema as SchemaCollection } from '@entity/schema'; +import { VcHelper } from '@helpers/vcHelper'; +import { SchemaHelper } from 'interfaces'; +import { Inject } from '@helpers/decorators/inject'; +import { Users } from '@helpers/users'; +import * as mathjs from 'mathjs'; + +@BasicBlock({ + blockType: 'customLogicBlock', + commonBlock: true +}) +export class CustomLogicBlock { + @Inject() + private users: Users; + + public start() { + console.log('Custom logic block'); + } + + @CatchErrors() + public async runAction(state: any, user: IAuthUser) { + const ref = PolicyComponentsUtils.GetBlockRef(this); + + try { + state.data = await this.execute(state, user); + await ref.runNext(user, state); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); + } catch (e) { + ref.error(e.message); + } + + } + + execute(state: any, user: IAuthUser): Promise { + return new Promise((resolve, reject) => { + const ref = PolicyComponentsUtils.GetBlockRef(this); + let documents = null; + if (Array.isArray(state.data)) { + documents = state.data; + } else { + documents = [state.data]; + } + + + + const done = async (result) => { + try { + const root = await this.users.getHederaAccount(ref.policyOwner); + const outputSchema = await getMongoRepository(SchemaCollection).findOne({ + iri: ref.options.outputSchema + }); + const context = SchemaHelper.getContext(outputSchema); + const owner = documents[0].owner; + const relationships = documents.filter(d => !!d.messageId).map(d => d.messageId); + const VCHelper = new VcHelper(); + + const processing = async (document) => { + + const newVC = await VCHelper.createVC( + root.did, + root.hederaAccountKey, + { + ...context, + ...document, + policyId: ref.policyId + } + ); + + + return { + hash: newVC.toCredentialHash(), + owner: owner, + document: newVC.toJsonTree(), + schema: outputSchema.iri, + type: outputSchema.iri, + policyId: ref.policyId, + tag: ref.tag, + messageId: null, + topicId: null, + relationships: relationships.length ? relationships : null + }; + } + + if (Array.isArray(result)) { + const items = []; + for (let r of result) { + items.push(await processing(r)) + } + resolve(items); + return; + } else { + resolve(await processing(result)); + return; + } + + } catch (e) { + reject(e); + } + } + + const func = Function(`const [done, user, documents, mathjs] = arguments; ${ref.options.expression}`); + func.apply(document, [done, user, documents, mathjs]); + }); + } +} diff --git a/guardian-service/src/policy-engine/blocks/index.ts b/guardian-service/src/policy-engine/blocks/index.ts index 4ae63c106d..489a5b963c 100644 --- a/guardian-service/src/policy-engine/blocks/index.ts +++ b/guardian-service/src/policy-engine/blocks/index.ts @@ -1,20 +1,23 @@ -export { PaginationAddon } from '@policy-engine/blocks/pagination-addon'; +export { AggregateBlock } from './aggregate-block'; +export { CalculateContainerBlock } from './calculate-block'; +export { CalculateMathAddon } from './calculate-math-addon'; +export { CustomLogicBlock } from '@policy-engine/blocks/custom-logic-block'; export { DocumentsSourceAddon } from './documents-source-addon'; -export { FiltersAddonBlock } from './filters-addon-block'; -export { PolicyRolesBlock } from './policy-roles'; export { ExternalDataBlock } from './external-data-block'; -export { MintBlock } from './mint-block'; -export { InterfaceStepBlock } from './interface-step-block'; +export { FiltersAddonBlock } from './filters-addon-block'; +export { InformationBlock } from './information-block'; +export { InterfaceContainerBlock } from './interface-container-block'; export { InterfaceDocumentActionBlock } from './interface-document-action-block'; export { InterfaceDocumentsSource } from './interface-documents-source'; -export { SendToGuardianBlock } from './send-to-guardian-block'; -export { RequestVcDocumentBlock } from './request-vc-document-block'; -export { InterfaceContainerBlock } from './interface-container-block'; -export { AggregateBlock } from './aggregate-block'; -export { RetirementBlock } from './retirement-block'; -export { InformationBlock } from './information-block'; -export { CalculateContainerBlock } from './calculate-block'; -export { CalculateMathAddon } from './calculate-math-addon'; +export { InterfaceStepBlock } from './interface-step-block'; +export { MintBlock } from './mint-block'; +export { PaginationAddon } from '@policy-engine/blocks/pagination-addon'; +export { PolicyRolesBlock } from './policy-roles'; +export { ReassigningBlock } from './reassigning.block'; export { ReportBlock } from './report-block'; export { ReportItemBlock } from './report-item-block'; -export { ReassigningBlock } from './reassigning.block'; +export { RetirementBlock } from './retirement-block'; +export { RequestVcDocumentBlock } from './request-vc-document-block'; +export { SendToGuardianBlock } from './send-to-guardian-block'; +export { SwitchBlock } from './switch-block'; +export { TimerBlock } from './timer-block'; \ No newline at end of file diff --git a/guardian-service/src/policy-engine/blocks/interface-document-action-block.ts b/guardian-service/src/policy-engine/blocks/interface-document-action-block.ts index 4f3c0bb5c9..20e98c7e80 100644 --- a/guardian-service/src/policy-engine/blocks/interface-document-action-block.ts +++ b/guardian-service/src/policy-engine/blocks/interface-document-action-block.ts @@ -7,7 +7,7 @@ import { Policy } from '@entity/policy'; import { Users } from '@helpers/users'; import { KeyType, Wallet } from '@helpers/wallet'; import { PolicyValidationResultsContainer } from '@policy-engine/policy-validation-results-container'; -import { Schema, UserType } from 'interfaces'; +import { UserType, Schema } from 'interfaces'; import { Schema as SchemaEntity } from '@entity/schema' import { findOptions } from '@policy-engine/helpers/find-options'; import { IPolicyAddonBlock, IPolicyInterfaceBlock } from '@policy-engine/policy-engine.interface'; @@ -61,7 +61,7 @@ export class InterfaceDocumentActionBlock { async setData(user: IAuthUser, document: any): Promise { const ref = PolicyComponentsUtils.GetBlockRef(this); - let state: any = {data: document}; + let state: any = { data: document }; if (ref.options.type == 'selector') { const option = this.findOptions(document, ref.options.field, ref.options.uiMetaData.options); @@ -84,7 +84,7 @@ export class InterfaceDocumentActionBlock { const userDID = userFull.did; const hederaAccountKey = await this.wallet.getKey(userFull.walletToken, KeyType.KEY, userDID); const sensorKey = await this.wallet.getKey(userFull.walletToken, KeyType.KEY, sensorDid); - const schemaObject = await getMongoRepository(SchemaEntity).findOne({iri: ref.options.schema}); + const schemaObject = await getMongoRepository(SchemaEntity).findOne({ iri: ref.options.schema }); const schema = new Schema(schemaObject); const didDocument = DidDocumentBase.createByPrivateKey(sensorDid, PrivateKey.fromString(sensorKey)); return { @@ -167,7 +167,7 @@ export class InterfaceDocumentActionBlock { break; } - const schema = await getMongoRepository(SchemaEntity).findOne({iri: ref.options.schema}); + const schema = await getMongoRepository(SchemaEntity).findOne({ iri: ref.options.schema }); if (!schema) { resultsContainer.addBlockError(ref.uuid, `Schema with id "${ref.options.schema}" does not exist`); break; diff --git a/guardian-service/src/policy-engine/blocks/interface-step-block.ts b/guardian-service/src/policy-engine/blocks/interface-step-block.ts index 8800a929d1..585d4dd0b7 100644 --- a/guardian-service/src/policy-engine/blocks/interface-step-block.ts +++ b/guardian-service/src/policy-engine/blocks/interface-step-block.ts @@ -37,8 +37,8 @@ export class InterfaceStepBlock { } ref.updateBlock(blockState, user); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, user); - PolicyComponentsUtils.CallParentContainerCallback(ref, user); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); } async getData(user: IAuthUser): Promise { diff --git a/guardian-service/src/policy-engine/blocks/mint-block.ts b/guardian-service/src/policy-engine/blocks/mint-block.ts index d48fa8bc09..92e4a7f35d 100644 --- a/guardian-service/src/policy-engine/blocks/mint-block.ts +++ b/guardian-service/src/policy-engine/blocks/mint-block.ts @@ -163,8 +163,8 @@ export class MintBlock { const root = await this.users.getHederaAccount(ref.policyOwner); const doc = await this.mintProcessing(token, vcs, vsMessages, topicId, rule, root, curUser, ref); await ref.runNext(curUser, state); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, curUser); - PolicyComponentsUtils.CallParentContainerCallback(ref, curUser); + ref.callDependencyCallbacks(curUser); + ref.callParentContainerCallback(curUser); } catch (e) { throw e; } diff --git a/guardian-service/src/policy-engine/blocks/reassigning.block.ts b/guardian-service/src/policy-engine/blocks/reassigning.block.ts index 04019a4860..2e06211856 100644 --- a/guardian-service/src/policy-engine/blocks/reassigning.block.ts +++ b/guardian-service/src/policy-engine/blocks/reassigning.block.ts @@ -71,8 +71,8 @@ export class ReassigningBlock { state.data = item; ref.log(`Reassigning Document: ${JSON.stringify(item)}`); await ref.runNext(owner, state); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, user); - PolicyComponentsUtils.CallParentContainerCallback(ref, user); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); // ref.updateBlock(state, user, ''); } } diff --git a/guardian-service/src/policy-engine/blocks/request-vc-document-block.ts b/guardian-service/src/policy-engine/blocks/request-vc-document-block.ts index 5a8d2ad62a..547a3c06dd 100644 --- a/guardian-service/src/policy-engine/blocks/request-vc-document-block.ts +++ b/guardian-service/src/policy-engine/blocks/request-vc-document-block.ts @@ -2,7 +2,7 @@ import { Inject } from '@helpers/decorators/inject'; import { KeyType, Wallet } from '@helpers/wallet'; import { BlockActionError } from '@policy-engine/errors'; import { PolicyComponentsUtils } from '../policy-components-utils'; -import { DidDocumentStatus, Schema, TopicType } from 'interfaces'; +import { DidDocumentStatus, TopicType, Schema } from 'interfaces'; import { IAuthUser } from '@auth/auth.interface'; import { EventBlock } from '../helpers/decorators/event-block'; import { PolicyValidationResultsContainer } from '@policy-engine/policy-validation-results-container'; @@ -44,8 +44,8 @@ export class RequestVcDocumentBlock { } blockState.active = active; ref.updateBlock(blockState, user); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, user); - PolicyComponentsUtils.CallParentContainerCallback(ref, user); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); } getActive(user: IAuthUser) { @@ -123,7 +123,7 @@ export class RequestVcDocumentBlock { credentialSubject.id = id; } - if (typeof(documentRef) === 'string') { + if (typeof (documentRef) === 'string') { credentialSubject.ref = documentRef; } else if (documentRef) { @@ -147,7 +147,7 @@ export class RequestVcDocumentBlock { relationships: null }; - if (typeof(documentRef) === 'object' && documentRef && documentRef.messageId) { + if (typeof (documentRef) === 'object' && documentRef && documentRef.messageId) { item.relationships = [documentRef.messageId]; } await this.changeActive(user, true); diff --git a/guardian-service/src/policy-engine/blocks/retirement-block.ts b/guardian-service/src/policy-engine/blocks/retirement-block.ts index 3c773d575e..035eedc7c3 100644 --- a/guardian-service/src/policy-engine/blocks/retirement-block.ts +++ b/guardian-service/src/policy-engine/blocks/retirement-block.ts @@ -162,8 +162,8 @@ export class RetirementBlock { const root = await this.users.getHederaAccount(ref.policyOwner); const doc = await this.retirementProcessing(token, vcs, vsMessages, topicId, rule, root, curUser, ref); await ref.runNext(curUser, state); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, curUser); - PolicyComponentsUtils.CallParentContainerCallback(ref, curUser); + ref.callDependencyCallbacks(curUser); + ref.callParentContainerCallback(curUser); } catch (e) { throw e; } diff --git a/guardian-service/src/policy-engine/blocks/send-to-guardian-block.ts b/guardian-service/src/policy-engine/blocks/send-to-guardian-block.ts index 070ab124d0..648e1a4487 100644 --- a/guardian-service/src/policy-engine/blocks/send-to-guardian-block.ts +++ b/guardian-service/src/policy-engine/blocks/send-to-guardian-block.ts @@ -171,10 +171,9 @@ export class SendToGuardianBlock { } } - async documentSender(state: any, user: IAuthUser): Promise { + async documentSender(document: any, user: IAuthUser): Promise { const ref = PolicyComponentsUtils.GetBlockRef(this); - let document = state.data; document.policyId = ref.policyId; document.tag = ref.tag; document.type = ref.options.entityType; @@ -182,7 +181,6 @@ export class SendToGuardianBlock { if (ref.options.forceNew) { document = { ...document }; document.id = undefined; - state.data = document; } if (ref.options.options) { document.option = document.option || {}; @@ -195,21 +193,34 @@ export class SendToGuardianBlock { ref.log(`Send Document: ${JSON.stringify(document)}`); if (ref.options.dataType) { - return await this.sendByType(document, user, ref); + document = await this.sendByType(document, user, ref); } else { - return await this.send(document, user, ref); + document = await this.send(document, user, ref); } + + return document; } @CatchErrors() async runAction(state: any, user: IAuthUser) { const ref = PolicyComponentsUtils.GetBlockRef(this); ref.log(`runAction`); - state.data = await this.documentSender(state, user); + + const docs: any | any[] = state.data; + if (Array.isArray(docs)) { + const newDocs = []; + for (let doc of docs) { + const newDoc = await this.documentSender(doc, user); + newDocs.push(newDoc); + } + state.data = newDocs; + } else { + state.data = await this.documentSender(docs, user); + } + await ref.runNext(user, state); - PolicyComponentsUtils.CallDependencyCallbacks(ref.tag, ref.policyId, user); - PolicyComponentsUtils.CallParentContainerCallback(ref, user); - // ref.updateBlock(state, user, ''); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); } public async validate(resultsContainer: PolicyValidationResultsContainer): Promise { @@ -235,6 +246,9 @@ export class SendToGuardianBlock { } } } + if (!ref.options.dataSource && !ref.options.dataType) { + resultsContainer.addBlockError(ref.uuid, 'Option "dataSource" must be one of database, hedera'); + } } catch (error) { resultsContainer.addBlockError(ref.uuid, `Unhandled exception ${error.message}`); } diff --git a/guardian-service/src/policy-engine/blocks/switch-block.ts b/guardian-service/src/policy-engine/blocks/switch-block.ts new file mode 100644 index 0000000000..6df76debd0 --- /dev/null +++ b/guardian-service/src/policy-engine/blocks/switch-block.ts @@ -0,0 +1,169 @@ +import { BasicBlock } from '@policy-engine/helpers/decorators'; +import { PolicyValidationResultsContainer } from '@policy-engine/policy-validation-results-container'; +import { PolicyComponentsUtils } from '../policy-components-utils'; +import { IAuthUser } from '@auth/auth.interface'; +import { VcDocument } from '@hedera-modules'; +import { Users } from '@helpers/users'; +import { Inject } from '@helpers/decorators/inject'; +import { PolicyUtils } from '@policy-engine/helpers/utils'; + +/** + * Switch block + */ +@BasicBlock({ + blockType: 'switchBlock', + commonBlock: true +}) +export class SwitchBlock { + @Inject() + private users: Users; + + private getScope(docs: any | any[]): any { + let result: any = {}; + if (!docs) { + return null; + } + if (Array.isArray(docs)) { + const scopes: any[] = []; + for (let doc of docs) { + if (doc.document) { + const element = VcDocument.fromJsonTree(doc.document); + const scope = PolicyUtils.getVCScope(element); + scopes.push(scope); + }; + } + result = this.aggregateScope(scopes); + } else { + const doc = docs; + if (!doc.document) { + return result; + }; + const element = VcDocument.fromJsonTree(doc.document); + result = PolicyUtils.getVCScope(element); + } + return result; + } + + private aggregateScope(scopes: any[]): any { + const result: any = {}; + if (!scopes || !scopes.length) { + return null; + } + const keys = Object.keys(scopes[0]); + for (let key of keys) { + result[key] = []; + } + for (let scope of scopes) { + for (let key of keys) { + result[key].push(scope[key]); + } + } + return result; + } + + async runAction(state: any, user: IAuthUser) { + const ref = PolicyComponentsUtils.GetBlockRef(this); + + ref.log(`switch: ${user?.did}`); + + const docs: any | any[] = state.data; + + let owner: string = null; + let issuer: string = null; + if (Array.isArray(docs)) { + owner = docs[0]?.owner; + issuer = docs[0]?.document?.issuer; + } else { + owner = docs?.owner; + issuer = docs?.document?.issuer; + + } + + const scope = this.getScope(docs); + + const { conditions, executionFlow } = ref.options; + for (let i = 0; i < conditions.length; i++) { + const condition = conditions[i]; + const type = condition.type; + const value = condition.value; + const actor = condition.actor; + const target = condition.target; + + let result = false; + if (type == 'equal') { + if (scope) { + result = PolicyUtils.evaluate(value, scope); + } else { + result = false; + } + } else if (type == 'not_equal') { + if (scope) { + result = !PolicyUtils.evaluate(value, scope); + } else { + result = false; + } + } else if (type == 'unconditional') { + result = true; + } + + let curUser: IAuthUser = user; + if (actor == 'owner' && owner) { + curUser = await this.users.getUserById(owner); + } else if (actor == 'issuer' && issuer) { + curUser = await this.users.getUserById(issuer); + } + + ref.log(`check condition: ${curUser?.did}, ${type}, ${value}, ${result}, ${JSON.stringify(scope)}`); + + if (result) { + const block = PolicyComponentsUtils.GetBlockByTag(ref.policyId, target) as any; + ref.runTarget(curUser, state, block).then(); + if (executionFlow == 'firstTrue') { + return; + } + } + } + } + + public async validate(resultsContainer: PolicyValidationResultsContainer): Promise { + const ref = PolicyComponentsUtils.GetBlockRef(this); + try { + if (!['firstTrue', 'allTrue'].find(item => item === ref.options.executionFlow)) { + resultsContainer.addBlockError(ref.uuid, 'Option "executionFlow" must be one of firstTrue, allTrue'); + } + + if (!ref.options.conditions) { + resultsContainer.addBlockError(ref.uuid, 'Option "conditions" does not set'); + } + + if (Array.isArray(ref.options.conditions)) { + for (let condition of ref.options.conditions) { + if (!['equal', 'not_equal', 'unconditional'].find(item => item === condition.type)) { + resultsContainer.addBlockError(ref.uuid, 'Option "condition.type" must be one of equal, not_equal, unconditional'); + } + if (!condition.target && !resultsContainer.isTagExist(condition.target)) { + resultsContainer.addBlockError(ref.uuid, `Tag "${condition.target}" does not exist`); + } + if (condition.target == ref.tag) { + resultsContainer.addBlockError(ref.uuid, `A block cannot redirect to itself`); + } + + if (condition.type == 'equal' || condition.type == 'not_equal') { + if (!condition.value) { + resultsContainer.addBlockError(ref.uuid, 'Option "condition.value" does not set'); + } else { + const vars = PolicyUtils.variables(condition.value); + } + } + + } + } else { + resultsContainer.addBlockError(ref.uuid, 'Option "conditions" must be an array'); + } + + + } catch (error) { + resultsContainer.addBlockError(ref.uuid, `Unhandled exception ${error.message}`); + } + } +} diff --git a/guardian-service/src/policy-engine/blocks/timer-block.ts b/guardian-service/src/policy-engine/blocks/timer-block.ts new file mode 100644 index 0000000000..1ef431f6d8 --- /dev/null +++ b/guardian-service/src/policy-engine/blocks/timer-block.ts @@ -0,0 +1,178 @@ +import moment from 'moment'; +import { CronJob } from 'cron'; +import { BasicBlock } from '@policy-engine/helpers/decorators'; +import { PolicyValidationResultsContainer } from '@policy-engine/policy-validation-results-container'; +import { PolicyComponentsUtils } from '../policy-components-utils'; +import { IAuthUser } from '@auth/auth.interface'; +import { AnyBlockType } from '@policy-engine/policy-engine.interface'; +import { Users } from '@helpers/users'; +import { Inject } from '@helpers/decorators/inject'; +import { StateField } from '@policy-engine/helpers/decorators'; + +/** + * Aggregate block + */ +@BasicBlock({ + blockType: 'timerBlock', + commonBlock: true +}) +export class TimerBlock { + @StateField() + private state: { [key: string]: boolean } = {}; + + @Inject() + private users: Users; + + private tickCount: number; + private interval: number; + private job: CronJob; + private endTime: number; + + start() { + const ref = PolicyComponentsUtils.GetBlockRef(this); + this.startCron(ref); + } + + destroy() { + if (this.job) { + this.job.stop(); + } + } + + private startCron(ref: AnyBlockType) { + try { + let sd = moment(ref.options.startDate).utc(); + if (sd.isValid()) { + sd = moment().utc(); + } + + this.endTime = Infinity; + if(ref.options.endDate) { + let ed = moment(ref.options.endDate).utc(); + if (ed.isValid()) { + this.endTime = ed.toDate().getTime(); + } + } + + const now = new Date(); + if (now.getTime() > this.endTime) { + return; + } + + let mask: string = ''; + this.interval = 0; + switch (ref.options.period) { + case 'yearly': { + mask = `${sd.minute()} ${sd.hour()} ${sd.date()} ${sd.month() + 1} *`; + break; + } + case 'monthly': { + mask = `${sd.minute()} ${sd.hour()} ${sd.date()} * *`; + break; + } + case 'weekly': { + mask = `${sd.minute()} ${sd.hour()} * * ${sd.weekday()}`; + break; + } + case 'daily': { + mask = `${sd.minute()} ${sd.hour()} * * *`; + break; + } + case 'hourly': { + mask = `${sd.minute()} * * * *`; + break; + } + case 'custom': { + mask = ref.options.periodMask; + this.interval = ref.options.periodInterval; + break; + } + } + ref.log(`start scheduler: ${mask}, ${ref.options.startDate}, ${ref.options.endDate}, ${ref.options.periodInterval}`); + if (this.interval > 1) { + this.tickCount = 0; + this.job = new CronJob(mask, () => { + const now = new Date(); + if (now.getTime() > this.endTime) { + ref.log(`stop scheduler: ${now.getTime()}, ${this.endTime}`); + this.job.stop(); + return; + } + this.tickCount++; + if (this.tickCount < this.interval) { + ref.log(`skip tick scheduler`); + return; + } + this.tickCount = 0; + this.tickCron(ref).then(); + }, null, false, 'UTC'); + } else { + this.job = new CronJob(mask, () => { + const now = new Date(); + if (now.getTime() > this.endTime) { + ref.log(`stop scheduler: ${now.getTime()}, ${this.endTime}`); + this.job.stop(); + return; + } + this.tickCron(ref).then(); + }, null, false, 'UTC'); + } + this.job.start(); + } catch (error) { + ref.log(`start scheduler fail ${error.message}`); + throw `start scheduler fail ${error.message}`; + } + } + + private async tickCron(ref: AnyBlockType) { + ref.log(`tick scheduler`); + + const users = Object.keys(this.state); + const map = []; + for (let did of users) { + if (this.state[did] === true) { + map.push(did); + } + } + + PolicyComponentsUtils.TriggerEvent({ + type: 'TimerEvent', + policyId: ref.policyId, + target: ref.tag, + targetId: ref.uuid, + user: null, + data: map + }) + } + + async runAction(state: any, user: IAuthUser) { + const ref = PolicyComponentsUtils.GetBlockRef(this); + const owner: string = state?.data?.owner; + if (owner) { + this.state[owner] = true; + ref.log(`start scheduler for: ${owner}`); + } + await ref.saveState(); + await ref.runNext(user, state); + ref.callDependencyCallbacks(user); + ref.callParentContainerCallback(user); + } + + public async validate(resultsContainer: PolicyValidationResultsContainer): Promise { + const ref = PolicyComponentsUtils.GetBlockRef(this); + try { + if (!ref.options.startDate) { + resultsContainer.addBlockError(ref.uuid, 'Option "startDate" does not set'); + } else if (typeof ref.options.startDate !== 'string') { + resultsContainer.addBlockError(ref.uuid, 'Option "startDate" must be a string'); + } + if (!ref.options.period) { + resultsContainer.addBlockError(ref.uuid, 'Option "period" does not set'); + } else if (typeof ref.options.period !== 'string') { + resultsContainer.addBlockError(ref.uuid, 'Option "period" must be a string'); + } + } catch (error) { + resultsContainer.addBlockError(ref.uuid, `Unhandled exception ${error.message}`); + } + } +} \ No newline at end of file diff --git a/guardian-service/src/policy-engine/helpers/decorators/basic-block.ts b/guardian-service/src/policy-engine/helpers/decorators/basic-block.ts index 97cbab5777..30a99fa6e0 100644 --- a/guardian-service/src/policy-engine/helpers/decorators/basic-block.ts +++ b/guardian-service/src/policy-engine/helpers/decorators/basic-block.ts @@ -12,6 +12,7 @@ import { BlockState } from '@entity/block-state'; import deepEqual from 'deep-equal'; import { BlockActionError } from '@policy-engine/errors'; import { Policy } from '@entity/policy'; +import { PolicyEvent } from '@policy-engine/interfaces/policy-event'; /** * Basic block decorator @@ -105,8 +106,6 @@ export function BasicBlock(options: Partial) { if (this.parent) { this.parent.registerChild(this as any as IPolicyBlock); } - - this.init(); } /** @@ -186,21 +185,21 @@ export function BasicBlock(options: Partial) { } } - public async updateBlock(state:any, user:IAuthUser, tag:string) { + public async updateBlock(state: any, user: IAuthUser, tag: string) { await this.saveState(); if (!this.options.followUser) { const policy = await getMongoRepository(Policy).findOne(this.policyId); for (let [did, role] of Object.entries(policy.registeredUsers)) { if (this.permissions.includes(role)) { - PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, {did} as any, tag); + PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, { did } as any, tag); } else if (this.permissions.includes('ANY_ROLE')) { - PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, {did} as any, tag); + PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, { did } as any, tag); } } if (this.permissions.includes('OWNER')) { - PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, {did: this.policyOwner} as any, tag); + PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, { did: this.policyOwner } as any, tag); } } else { PolicyComponentsUtils.BlockUpdateFn(this.uuid, state, user, tag); @@ -222,7 +221,7 @@ export function BasicBlock(options: Partial) { return this.parent.isChildActive(this as any, user); } - private async saveState(): Promise { + public async saveState(): Promise { const stateFields = PolicyComponentsUtils.GetStateFields(this); if (stateFields && (Object.keys(stateFields).length > 0) && this.policyId) { const repo = getMongoRepository(BlockState); @@ -313,17 +312,45 @@ export function BasicBlock(options: Partial) { } public destroy() { + if (typeof super.destroy === 'function') { + super.destroy(); + } + for (let child of (this as any).children) { child.destroy(); } } - private init() { - if (typeof super.init === 'function') { - super.init(); + public start() { + for (let dep of this.dependencies) { + PolicyComponentsUtils.RegisterEvent( + this.policyId, dep, 'DependencyEvent', (event: PolicyEvent) => { + this.updateBlock({}, event.user, ''); + } + ); + } + if (typeof super.start === 'function') { + super.start(); } } + public callDependencyCallbacks(user: IAuthUser) { + PolicyComponentsUtils.TriggerEvent({ + type: 'DependencyEvent', + policyId: this.policyId, + target: this.tag, + targetId: this.uuid, + user: user, + data: null + }); + } + + public callParentContainerCallback(user: IAuthUser) { + if (this.parent?.blockClassName === 'ContainerBlock') { + this.parent.updateBlock({}, user, ''); + } + } + protected log(message: string) { this.logger.info(message, ['GUARDIAN_SERVICE', this.uuid, this.blockType, this.tag, this.policyId]); } diff --git a/guardian-service/src/policy-engine/helpers/policy-import-export-helper.ts b/guardian-service/src/policy-engine/helpers/policy-import-export-helper.ts index 4079d3fecc..03af10b499 100644 --- a/guardian-service/src/policy-engine/helpers/policy-import-export-helper.ts +++ b/guardian-service/src/policy-engine/helpers/policy-import-export-helper.ts @@ -11,12 +11,13 @@ import { getMongoRepository } from 'typeorm'; import { GenerateUUIDv4 } from '@policy-engine/helpers/uuidv4'; import { Token } from '@entity/token'; import { Schema } from '@entity/schema'; -import { ModelHelper, SchemaHelper, SchemaStatus, TopicType } from 'interfaces'; +import { TopicType } from 'interfaces'; import { Users } from '@helpers/users'; import { HederaSDKHelper, MessageAction, MessageServer, MessageType, PolicyMessage } from '@hedera-modules'; import { Topic } from '@entity/topic'; import { importSchemaByFiles } from '@api/schema.service'; import { TopicHelper } from '@helpers/topicHelper'; +import { PrivateKey } from '@hashgraph/sdk'; export class PolicyImportExportHelper { /** @@ -61,6 +62,13 @@ export class PolicyImportExportHelper { const zip = new JSZip(); zip.folder('tokens') for (let token of tokens) { + delete token.adminId; + delete token.owner; + token.adminKey = token.adminKey ? "..." : null; + token.kycKey = token.kycKey ? "..." : null; + token.wipeKey = token.wipeKey ? "..." : null; + token.supplyKey = token.supplyKey ? "..." : null; + token.freezeKey = token.freezeKey ? "..." : null; zip.file(`tokens/${token.tokenName}.json`, JSON.stringify(token)); } zip.folder('schemes') @@ -152,22 +160,20 @@ export class PolicyImportExportHelper { // Import Tokens if (tokens) { const client = new HederaSDKHelper(root.hederaAccountId, root.hederaAccountKey); + const rootHederaAccountKey = PrivateKey.fromString(root.hederaAccountKey); const tokenRepository = getMongoRepository(Token); for (const token of tokens) { - const treasury = await client.newAccount(); - const treasuryId = treasury.id; - const treasuryKey = treasury.key; const tokenName = token.tokenName; const tokenSymbol = token.tokenSymbol; const tokenType = token.tokenType; const nft = tokenType == 'non-fungible'; const decimals = nft ? 0 : token.decimals; const initialSupply = nft ? 0 : token.initialSupply; - const adminKey = token.adminKey ? treasuryKey : null; - const kycKey = token.kycKey ? treasuryKey : null; - const freezeKey = token.freezeKey ? treasuryKey : null; - const wipeKey = token.wipeKey ? treasuryKey : null; - const supplyKey = token.supplyKey ? treasuryKey : null; + const adminKey = token.adminKey ? rootHederaAccountKey : null; + const kycKey = token.kycKey ? rootHederaAccountKey : null; + const freezeKey = token.freezeKey ? rootHederaAccountKey : null; + const wipeKey = token.wipeKey ? rootHederaAccountKey : null; + const supplyKey = token.supplyKey ? rootHederaAccountKey : null; const tokenId = await client.newToken( tokenName, tokenSymbol, @@ -175,7 +181,10 @@ export class PolicyImportExportHelper { decimals, initialSupply, '', - treasury, + { + id: root.hederaAccountId, + key: rootHederaAccountKey + }, adminKey, kycKey, freezeKey, @@ -189,7 +198,7 @@ export class PolicyImportExportHelper { tokenType, decimals: decimals, initialSupply: initialSupply, - adminId: treasuryId ? treasuryId.toString() : null, + adminId: root.hederaAccountId, adminKey: adminKey ? adminKey.toString() : null, kycKey: kycKey ? kycKey.toString() : null, freezeKey: freezeKey ? freezeKey.toString() : null, diff --git a/guardian-service/src/policy-engine/helpers/utils.ts b/guardian-service/src/policy-engine/helpers/utils.ts index 2ffda5173e..1306726bcf 100644 --- a/guardian-service/src/policy-engine/helpers/utils.ts +++ b/guardian-service/src/policy-engine/helpers/utils.ts @@ -19,7 +19,13 @@ export enum DataTypes { } export class PolicyUtils { - private static evaluate(formula: string, scope: any) { + public static variables(formula: string): string[] { + return mathjs.parse(formula) + .filter((node: any) => node.isSymbolNode) + .map((node: any) => node.name); + } + + public static evaluate(formula: string, scope: any) { return (function (formula: string, scope: any) { try { return this.evaluate(formula, scope); @@ -30,7 +36,7 @@ export class PolicyUtils { } public static getVCScope(item: VcDocument) { - return item.getCredentialSubject(0).toJsonTree(); + return item.getCredentialSubject(0).getFields(); } public static aggregate(rule: string, vcs: VcDocument[]): number { @@ -251,4 +257,4 @@ export class PolicyUtils { } return null; } -} \ No newline at end of file +} diff --git a/guardian-service/src/policy-engine/interfaces/policy-event.ts b/guardian-service/src/policy-engine/interfaces/policy-event.ts new file mode 100644 index 0000000000..b61695d4e0 --- /dev/null +++ b/guardian-service/src/policy-engine/interfaces/policy-event.ts @@ -0,0 +1,10 @@ +import { IAuthUser } from "@auth/auth.interface"; + +export interface PolicyEvent { + type: string; // Event Type; + target: string; // Block Tag; + policyId: string; // Policy Id; + targetId: string; // Block Id; + user?: IAuthUser; + data?: T; +} \ No newline at end of file diff --git a/guardian-service/src/policy-engine/policy-components-utils.ts b/guardian-service/src/policy-engine/policy-components-utils.ts index 0569d35f26..d78a707948 100644 --- a/guardian-service/src/policy-engine/policy-components-utils.ts +++ b/guardian-service/src/policy-engine/policy-components-utils.ts @@ -13,6 +13,7 @@ import { Policy } from '@entity/policy'; import { STATE_KEY } from '@policy-engine/helpers/constants'; import { GetBlockByType } from '@policy-engine/blocks/get-block-by-type'; import { GetOtherOptions } from '@policy-engine/helpers/get-other-options'; +import { PolicyEvent } from './interfaces/policy-event'; export class PolicyComponentsUtils { public static BlockUpdateFn: (uuid: string, state: any, user: IAuthUser, tag?: string) => void; @@ -20,34 +21,64 @@ export class PolicyComponentsUtils { private static ExternalDataBlocks: Map = new Map(); private static PolicyBlockMapObject: PolicyBlockMap = new Map(); private static PolicyTagMapObject: Map = new Map(); - private static BlockSubscriptions: Map> = new Map(); + private static BlockEventSubscriptions: Map>> = new Map(); - /** - * Register dependency - * @param tag {string} - * @param fn {Function} - */ - public static RegisterDependencyCallback(tag: string, policyId: string, fn: Function): void { - let policyTagsMap: Map; + public static RegisterEvent(policyId: string, tag: string, eventType: string, fn: Function): void { + let policyMap: Map>; + if (PolicyComponentsUtils.BlockEventSubscriptions.has(policyId)) { + policyMap = PolicyComponentsUtils.BlockEventSubscriptions.get(policyId); + } else { + policyMap = new Map(); + PolicyComponentsUtils.BlockEventSubscriptions.set(policyId, policyMap); + } - if (!PolicyComponentsUtils.BlockSubscriptions.has(policyId)) { - policyTagsMap = new Map(); - PolicyComponentsUtils.BlockSubscriptions.set(policyId, policyTagsMap); + let tagMap: Map; + if (policyMap.has(tag)) { + tagMap = policyMap.get(tag); } else { - policyTagsMap = PolicyComponentsUtils.BlockSubscriptions.get(policyId); + tagMap = new Map(); + policyMap.set(tag, tagMap); } let subscriptionsArray: Function[]; - if (!Array.isArray(policyTagsMap.get(tag))) { + if (!Array.isArray(tagMap.get(eventType))) { subscriptionsArray = []; - policyTagsMap.set(tag, subscriptionsArray); + tagMap.set(eventType, subscriptionsArray); } else { - subscriptionsArray = policyTagsMap.get(tag); + subscriptionsArray = tagMap.get(eventType); } subscriptionsArray.push(fn); } + public static RemoveEventAll(policyId: string, tag: string, eventType: string): void { + if (PolicyComponentsUtils.BlockEventSubscriptions.has(policyId)) { + const policy = PolicyComponentsUtils.BlockEventSubscriptions.get(policyId); + if (policy.has(tag)) { + const block = policy.get(tag); + if (block.has(eventType)) { + block.set(eventType, []); + } + } + } + } + + public static TriggerEvent(event: PolicyEvent): void { + if (PolicyComponentsUtils.BlockEventSubscriptions.has(event.policyId)) { + const policy = PolicyComponentsUtils.BlockEventSubscriptions.get(event.policyId); + if (policy.has(event.target)) { + const block = policy.get(event.target); + if (block.has(event.type)) { + const functions = block.get(event.type); + for (let i = 0; i < functions.length; i++) { + const fn = functions[i]; + fn(event); + } + } + } + } + } + /** * Return new uniq id for block */ @@ -84,37 +115,7 @@ export class PolicyComponentsUtils { PolicyComponentsUtils.ExternalDataBlocks.set(component.uuid, component); } - const componentRef = component as any; - for (let dep of componentRef.dependencies) { - PolicyComponentsUtils.RegisterDependencyCallback(dep, policyId, (user) => { - component.updateBlock({}, user, ''); - }) - } - } - - /** - * Call callbacks of all dependency blocks - * @param tag - * @param policyId - * @param user - */ - public static CallDependencyCallbacks(tag: string, policyId: string, user: any): void { - if (PolicyComponentsUtils.BlockSubscriptions.has(policyId) && PolicyComponentsUtils.BlockSubscriptions.get(policyId).has(tag)) { - for (let fn of PolicyComponentsUtils.BlockSubscriptions.get(policyId).get(tag)) { - fn(user); - } - } - } - - /** - * Find and block container parent - * @param block - * @param user - */ - public static CallParentContainerCallback(block: AnyBlockType, user: any): void { - if (block.parent?.blockClassName === 'ContainerBlock') { - block.parent.updateBlock({}, user, ''); - } + component.start(); } /** @@ -123,7 +124,7 @@ export class PolicyComponentsUtils { */ public static async ReceiveExternalData(data: any): Promise { for (let block of PolicyComponentsUtils.ExternalDataBlocks.values()) { - const policy = await getMongoRepository(Policy).findOne({policyTag: data.policyTag}); + const policy = await getMongoRepository(Policy).findOne({ policyTag: data.policyTag }); if (policy.id.toString() === (block as any).policyId) { await (block as any).receiveData(data); } @@ -182,8 +183,8 @@ export class PolicyComponentsUtils { * @param skipRegistration */ public static ConfigureBlock(policyId: string, blockType: string, - options: Partial, - skipRegistration?: boolean): any { + options: Partial, + skipRegistration?: boolean): any { if (options.options) { options = Object.assign(options, options.options); } @@ -197,6 +198,7 @@ export class PolicyComponentsUtils { options._parent, GetOtherOptions(options as PolicyBlockFullArgumentList) ); + instance.setPolicyId(policyId); if (!skipRegistration) { PolicyComponentsUtils.RegisterComponent(policyId, instance); } @@ -218,4 +220,4 @@ export class PolicyComponentsUtils { public static GetBlockUniqueOptionsObject(obj: any): { [key: string]: any } { return obj.options; } -} +} \ No newline at end of file diff --git a/guardian-service/src/policy-engine/policy-engine.interface.ts b/guardian-service/src/policy-engine/policy-engine.interface.ts index 015ef33297..2eef2d8642 100644 --- a/guardian-service/src/policy-engine/policy-engine.interface.ts +++ b/guardian-service/src/policy-engine/policy-engine.interface.ts @@ -61,6 +61,14 @@ export interface IPolicyBlock { error(message: string): void; warn(message: string): void; + + start(); + + callDependencyCallbacks(user: IAuthUser); + + callParentContainerCallback(user: IAuthUser); + + saveState(): Promise; } export interface IPolicyInterfaceBlock extends IPolicyBlock { diff --git a/guardian-service/src/policy-engine/policy-engine.service.ts b/guardian-service/src/policy-engine/policy-engine.service.ts index 5cbdecae1c..0c0d5773ff 100644 --- a/guardian-service/src/policy-engine/policy-engine.service.ts +++ b/guardian-service/src/policy-engine/policy-engine.service.ts @@ -1,12 +1,10 @@ import { - MessageError, - MessageResponse, - ModelHelper, PolicyEngineEvents, SchemaEntity, - SchemaHelper, SchemaStatus, - TopicType + TopicType, + ModelHelper, + SchemaHelper } from 'interfaces'; import { findAllEntities, @@ -40,15 +38,16 @@ import { PolicyComponentsUtils } from './policy-components-utils'; import { BlockTreeGenerator } from './block-tree-generator'; import { Topic } from '@entity/topic'; import { TopicHelper } from '@helpers/topicHelper'; +import { MessageBrokerChannel, MessageResponse, MessageError, BinaryMessageResponse } from 'common'; export class PolicyEngineService { @Inject() private users: Users; - private channel: any; + private channel: MessageBrokerChannel; private policyGenerator: BlockTreeGenerator; - constructor(channel: any) { + constructor(channel: MessageBrokerChannel) { this.channel = channel; this.policyGenerator = new BlockTreeGenerator(); @@ -76,7 +75,7 @@ export class PolicyEngineService { const role = policy.registeredUsers[user.did]; if (PolicyComponentsUtils.IfUUIDRegistered(uuid) && PolicyComponentsUtils.IfHasPermission(uuid, role, user)) { - await this.channel.request('api-gateway', 'update-block', { + await this.channel.request(['api-gateway', 'update-block'].join('.'), { uuid, state, user @@ -89,7 +88,7 @@ export class PolicyEngineService { return; } - await this.channel.request('api-gateway', 'block-error', { + await this.channel.request(['api-gateway', 'block-error'].join('.'), { blockType, message, user @@ -260,13 +259,13 @@ export class PolicyEngineService { * @private */ public registerListeners(): void { - this.channel.response('mrv-data', async (msg, res) => { - await PolicyComponentsUtils.ReceiveExternalData(msg.payload); - res.send(); + this.channel.response('mrv-data', async (msg) => { + await PolicyComponentsUtils.ReceiveExternalData(msg); + return new MessageResponse({}) }); - this.channel.response(PolicyEngineEvents.GET_POLICY, async (msg, res) => { - const { filters, userDid } = msg.payload; + this.channel.response(PolicyEngineEvents.GET_POLICY, async (msg) => { + const { filters, userDid } = msg; const data: any = await getMongoRepository(Policy).findOne(filters); if (data) { if (userDid) { @@ -283,12 +282,12 @@ export class PolicyEngineService { } delete data.registeredUsers; } - res.send(new MessageResponse(data)); + return new MessageResponse(data); }); - this.channel.response(PolicyEngineEvents.GET_POLICIES, async (msg, res) => { + this.channel.response(PolicyEngineEvents.GET_POLICIES, async (msg) => { try { - const { filters, pageIndex, pageSize, userDid } = msg.payload; + const { filters, pageIndex, pageSize, userDid } = msg; const filter: any = { where: filters } const _pageSize = parseInt(pageSize, 10); const _pageIndex = parseInt(pageIndex, 10); @@ -316,48 +315,48 @@ export class PolicyEngineService { delete policy.registeredUsers; }); - res.send(new MessageResponse({ policies, count })); + return new MessageResponse({ policies, count }); } catch (error) { - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.CREATE_POLICIES, async (msg, res) => { + this.channel.response(PolicyEngineEvents.CREATE_POLICIES, async (msg) => { try { - const user = msg.payload.user; + const user = msg.user; const userFull = await this.users.getUser(user.username); - await this.createPolicy(msg.payload.model, userFull.did); + await this.createPolicy(msg.model, userFull.did); const policies = await getMongoRepository(Policy).find({ owner: userFull.did }); policies.forEach(p => { delete p.registeredUsers; }); - res.send(new MessageResponse(policies)); + return new MessageResponse(policies); } catch (error) { - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.SAVE_POLICIES, async (msg, res) => { + this.channel.response(PolicyEngineEvents.SAVE_POLICIES, async (msg) => { try { - const result = await this.updatePolicy(msg.payload.policyId, msg.payload.model); + const result = await this.updatePolicy(msg.policyId, msg.model); delete result.registeredUsers; - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.PUBLISH_POLICIES, async (msg, res) => { + this.channel.response(PolicyEngineEvents.PUBLISH_POLICIES, async (msg) => { try { - if (!msg.payload.model || !msg.payload.model.policyVersion) { + if (!msg.model || !msg.model.policyVersion) { throw new Error('Policy version in body is empty'); } - const policyId = msg.payload.policyId; - const version = msg.payload.model.policyVersion; - const user = msg.payload.user; + const policyId = msg.policyId; + const version = msg.model.policyVersion; + const user = msg.user; const userFull = await this.users.getUser(user.username); const owner = userFull.did; @@ -395,84 +394,84 @@ export class PolicyEngineService { return item; }); - res.send(new MessageResponse({ + return new MessageResponse({ policies: policies, isValid, errors - })); + }); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); console.error(error.message); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.VALIDATE_POLICIES, async (msg, res) => { + this.channel.response(PolicyEngineEvents.VALIDATE_POLICIES, async (msg) => { try { - const policy = msg.payload.model as Policy; + const policy = msg.model as Policy; const results = await this.policyGenerator.validate(policy); delete policy.registeredUsers; - res.send(new MessageResponse({ + return new MessageResponse({ results, policy - })); + }); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_BLOCKS, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_BLOCKS, async (msg) => { try { - const block = this.policyGenerator.getRoot(msg.payload.policyId); - const user = msg.payload.user; + const block = this.policyGenerator.getRoot(msg.policyId); + const user = msg.user; const userFull = await this.users.getUser(user.username); - res.send(new MessageResponse(await block.getData(userFull, block.uuid))); + return new MessageResponse(await block.getData(userFull, block.uuid)); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); console.error(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.GET_BLOCK_DATA, async (msg, res) => { + this.channel.response(PolicyEngineEvents.GET_BLOCK_DATA, async (msg) => { try { - const { user, blockId, policyId } = msg.payload; + const { user, blockId, policyId } = msg; const userFull = await this.users.getUser(user.username); const data = await (PolicyComponentsUtils.GetBlockByUUID(blockId) as IPolicyInterfaceBlock).getData(userFull, blockId, null) - res.send(new MessageResponse(data)); + return new MessageResponse(data); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.SET_BLOCK_DATA, async (msg, res) => { + this.channel.response(PolicyEngineEvents.SET_BLOCK_DATA, async (msg) => { try { - const { user, blockId, policyId, data } = msg.payload; + const { user, blockId, policyId, data } = msg; const userFull = await this.users.getUser(user.username); const result = await (PolicyComponentsUtils.GetBlockByUUID(blockId) as IPolicyInterfaceBlock).setData(userFull, data) - res.send(new MessageResponse(result)); + return new MessageResponse(result); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.BLOCK_BY_TAG, async (msg, res) => { + this.channel.response(PolicyEngineEvents.BLOCK_BY_TAG, async (msg) => { try { - const { user, tag, policyId } = msg.payload; + const { user, tag, policyId } = msg; const userFull = await this.users.getUser(user.username); const block = PolicyComponentsUtils.GetBlockByTag(policyId, tag); - res.send(new MessageResponse({ id: block.uuid })); + return new MessageResponse({ id: block.uuid }); } catch (error) { - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.GET_BLOCK_PARENTS, async (msg, res) => { + this.channel.response(PolicyEngineEvents.GET_BLOCK_PARENTS, async (msg) => { try { - const { user, blockId, policyId, data } = msg.payload; + const { user, blockId, policyId, data } = msg; const userFull = await this.users.getUser(user.username); const block = PolicyComponentsUtils.GetBlockByUUID(blockId) as IPolicyInterfaceBlock; let tmpBlock: IPolicyBlock = block; @@ -481,69 +480,70 @@ export class PolicyEngineService { parents.push(tmpBlock.parent.uuid); tmpBlock = tmpBlock.parent; } - res.send(new MessageResponse(parents)); + return new MessageResponse(parents); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_EXPORT_FILE, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_EXPORT_FILE, async (msg) => { try { - const { policyId } = msg.payload; + const { policyId } = msg; const policy = await getMongoRepository(Policy).findOne(policyId); if (!policy) { throw new Error(`Cannot export policy ${policyId}`); } const zip = await PolicyImportExportHelper.generateZipFile(policy); const file = await zip.generateAsync({ type: 'arraybuffer' }); - res.send(file, 'raw'); + console.log("File size: " + file.byteLength); + return new BinaryMessageResponse(file); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); console.log(error); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_EXPORT_MESSAGE, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_EXPORT_MESSAGE, async (msg) => { try { - const { policyId } = msg.payload; + const { policyId } = msg; const policy = await getMongoRepository(Policy).findOne(policyId); if (!policy) { throw new Error(`Cannot export policy ${policyId}`); } - res.send(new MessageResponse({ + return new MessageResponse({ id: policy.id, name: policy.name, description: policy.description, version: policy.version, messageId: policy.messageId, owner: policy.owner - })); + }); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_IMPORT_FILE_PREVIEW, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_IMPORT_FILE_PREVIEW, async (msg) => { try { - const { zip, user } = msg.payload; + const { zip, user } = msg; if (!zip) { throw new Error('file in body is empty'); } const userFull = await this.users.getUser(user.username); const policyToImport = await PolicyImportExportHelper.parseZipFile(Buffer.from(zip.data)); - res.send(new MessageResponse(policyToImport)); + return new MessageResponse(policyToImport); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_IMPORT_FILE, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_IMPORT_FILE, async (msg) => { try { - const { zip, user } = msg.payload; + const { zip, user } = msg; if (!zip) { throw new Error('file in body is empty'); } @@ -551,16 +551,16 @@ export class PolicyEngineService { const policyToImport = await PolicyImportExportHelper.parseZipFile(Buffer.from(zip.data)); const policy = await PolicyImportExportHelper.importPolicy(policyToImport, userFull.did); const policies = await getMongoRepository(Policy).find({ owner: userFull.did }); - res.send(new MessageResponse(policies)); + return new MessageResponse(policies); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_IMPORT_MESSAGE_PREVIEW, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_IMPORT_MESSAGE_PREVIEW, async (msg) => { try { - const { messageId, user } = msg.payload; + const { messageId, user } = msg; const userFull = await this.users.getUser(user.username); if (!messageId) { throw new Error('Policy ID in body is empty'); @@ -599,16 +599,16 @@ export class PolicyEngineService { policyToImport.newVersions = newVersions.reverse(); } - res.send(new MessageResponse(policyToImport)); + return new MessageResponse(policyToImport); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.POLICY_IMPORT_MESSAGE, async (msg, res) => { + this.channel.response(PolicyEngineEvents.POLICY_IMPORT_MESSAGE, async (msg) => { try { - const { messageId, user } = msg.payload; + const { messageId, user } = msg; const userFull = await this.users.getUser(user.username); if (!messageId) { throw new Error('Policy ID in body is empty'); @@ -629,20 +629,20 @@ export class PolicyEngineService { const policyToImport = await PolicyImportExportHelper.parseZipFile(message.document); const policy = await PolicyImportExportHelper.importPolicy(policyToImport, userFull.did); const policies = await getMongoRepository(Policy).find({ owner: userFull.did }); - res.send(new MessageResponse(policies)); + return new MessageResponse(policies); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); - this.channel.response(PolicyEngineEvents.RECEIVE_EXTERNAL_DATA, async (msg, res) => { + this.channel.response(PolicyEngineEvents.RECEIVE_EXTERNAL_DATA, async (msg) => { try { - await PolicyComponentsUtils.ReceiveExternalData(msg.payload); - res.send(new MessageResponse(true)); + await PolicyComponentsUtils.ReceiveExternalData(msg); + return new MessageResponse(true); } catch (error) { new Logger().error(error.toString(), ['GUARDIAN_SERVICE']); - res.send(new MessageError(error.message)); + return new MessageError(error.message); } }); } diff --git a/guardian-service/tests/api/approve.service.test.js b/guardian-service/tests/api/approve.service.test.js new file mode 100644 index 0000000000..88047ace5b --- /dev/null +++ b/guardian-service/tests/api/approve.service.test.js @@ -0,0 +1,101 @@ +require('module-alias/register'); +const { expect, assert } = require('chai'); +const rewire = require("rewire"); +const { ApprovalDocument } = require("../../dist/entity/approval-document"); + +const { ApplicationState, MessageResponse } = require("common"); +const state = new ApplicationState(); +state.updateState('READY'); + +const approveAPIModule = rewire("../../dist/api/approve.service"); + +class MockLogger { + constructor() { + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +class MockUsers { + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } +} + +function getMongoRepositoryMock(entity) { + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + return instance; + }, + update: async function (obj) { + return instance; + } + } +} + +const methods = { + 'get-approve-documents': function (...args) { + } +} + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + } +} + +describe.only('Approve Service API', function () { + it('Get Approve Documents', async function () { + approveAPIModule.approveAPI(channel, getMongoRepositoryMock(ApprovalDocument)); + + const data = await methods['get-approve-documents']({ id: 'test' }); + assert.equal(data.body[0] instanceof ApprovalDocument, true); + + }); + + it('Update Approve Document', async function () { + approveAPIModule.approveAPI(channel, getMongoRepositoryMock(ApprovalDocument)); + const data = await methods['update-approve-documents']({ id: 'test' }); + assert.equal(data.body instanceof ApprovalDocument, true); + }) +}); diff --git a/guardian-service/tests/api/config.service.test.js b/guardian-service/tests/api/config.service.test.js new file mode 100644 index 0000000000..de71933179 --- /dev/null +++ b/guardian-service/tests/api/config.service.test.js @@ -0,0 +1,123 @@ +require('module-alias/register'); +const { expect, assert } = require('chai'); +const rewire = require("rewire"); + +const { ApplicationState } = require("common"); +const { Settings } = require("../../dist/entity/settings"); +const { Topic } = require("../../dist/entity/topic"); +const state = new ApplicationState(); +state.updateState('READY'); + +const configAPIModule = rewire("../../dist/api/config.service"); + +class MockLogger { + constructor() { + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +configAPIModule.__set__('logger_helper_1', { + Logger: MockLogger +}); + +class MockUsers { + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } +} + +function getMongoRepositoryMock(entity) { + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + return instance; + }, + update: async function (obj) { + return instance; + } + } +} + +const methods = { + 'GET_TOPIC': function (...args) { + }, + 'UPDATE_SETTINGS': function (...args) { + }, + 'GET_SETTINGS': function (...args) { + } +} + +const res = { + send: function (data) { + assert.equal(typeof data.body === 'object', true); + } +} + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + } +} + +describe('Config Service API', function () { + it('Get Topic', async function () { + await configAPIModule.configAPI(channel, getMongoRepositoryMock(Settings), getMongoRepositoryMock(Topic)); + const data = await methods['GET_TOPIC'](); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Update Settings', async function () { + await configAPIModule.configAPI(channel, getMongoRepositoryMock(Settings), getMongoRepositoryMock(Topic)); + const data = await methods['UPDATE_SETTINGS']({ operatorId: 'test' }) + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Get Settings', async function () { + await configAPIModule.configAPI(channel, getMongoRepositoryMock(Settings), getMongoRepositoryMock(Topic)); + const data = await methods['GET_SETTINGS']() + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) +}) diff --git a/guardian-service/tests/api/documents.service.test.js b/guardian-service/tests/api/documents.service.test.js new file mode 100644 index 0000000000..cf5918c686 --- /dev/null +++ b/guardian-service/tests/api/documents.service.test.js @@ -0,0 +1,148 @@ +require('module-alias/register'); +const { expect, assert } = require('chai'); +const rewire = require("rewire"); + +const { ApplicationState } = require("common"); +const { DidDocument } = require("../../dist/entity/did-document"); +const { VcDocument } = require("../../dist/entity/vc-document"); +const { VpDocument } = require("../../dist/entity/vp-document"); +const state = new ApplicationState(); +state.updateState('READY'); + +const documentsAPIModule = rewire("../../dist/api/documents.service"); + +class MockLogger { + constructor() { + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +class MockUsers { + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } +} + +function getMongoRepositoryMock(entity) { + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + case 'DidDocument': + Object.assign(instance, { document: {} }); + return instance; + + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + return instance; + }, + update: async function (obj) { + return instance; + } + } +} + +const methods = { + 'get-did-documents': function (...args) { + }, + 'get-vc-documents': function (...args) { + }, + 'set-did-document': function (...args) { + }, + 'set-vc-document': function (...args) { + }, + 'set-vp-document': function (...args) { + }, + 'get-vp-documents': function (...args) { + } +} + + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + } +} + +describe('Documents Service API', function () { + it('Get DID Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['get-did-documents']({ did: 'test' }); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + + }) + + it('Get VC Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['get-vc-documents'](); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Get DID Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['set-did-document']({ did: 'test' }); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + + }) + + it('Set VC Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['set-vc-document']({ hash: 'test' }); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Set VP Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['set-vp-document'](); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Set VP Documents', async function () { + await documentsAPIModule.documentsAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(VcDocument), getMongoRepositoryMock(VpDocument)); + const data = await methods['get-vp-documents'](); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) +}) diff --git a/guardian-service/tests/api/loader.service.test.js b/guardian-service/tests/api/loader.service.test.js new file mode 100644 index 0000000000..2fac01d7d0 --- /dev/null +++ b/guardian-service/tests/api/loader.service.test.js @@ -0,0 +1,133 @@ +require('module-alias/register'); +const { expect, assert } = require('chai'); +const rewire = require("rewire"); + +const { ApplicationState } = require("common"); +const { DidDocument } = require("../../dist/entity/did-document"); +const { Schema } = require("../../dist/entity/schema"); +const state = new ApplicationState(); +state.updateState('READY'); + +const loaderAPIModule = rewire("../../dist/api/loader.service"); + +class MockLogger { + constructor() { + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +loaderAPIModule.__set__('logger_helper_1', { + Logger: MockLogger +}); + +loaderAPIModule.__set__('_hedera_modules_1', { + DidRootKey: { + create: function () { + return { + getController: function () { + return 'did'; + } + } + } + } +}); + +class MockUsers { + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } +} + +function getMongoRepositoryMock(entity) { + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + case 'DidDocument': + Object.assign(instance, { document: {} }); + return instance; + + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + return instance; + }, + update: async function (obj) { + return instance; + } + } +} + +const methods = { + 'load-did-document': function (...args) { + }, + 'load-schema-document': function (...args) { + }, + 'load-schema-context': function (...args) { + } +} + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + } +} + +describe('Loader Service API', function () { + it('Load DID Document', async function () { + await loaderAPIModule.loaderAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(Schema)); + const data = await methods['load-did-document']({ did: 'test' }); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Load Schema Document', async function () { + await loaderAPIModule.loaderAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(Schema)); + const data = await methods['load-schema-document']({}); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Load Schema Context', async function () { + await loaderAPIModule.loaderAPI(channel, getMongoRepositoryMock(DidDocument), getMongoRepositoryMock(Schema)); + const data = await methods['load-schema-context']({}); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) +}) diff --git a/guardian-service/tests/api/profile.service.test.js b/guardian-service/tests/api/profile.service.test.js new file mode 100644 index 0000000000..de83813a98 --- /dev/null +++ b/guardian-service/tests/api/profile.service.test.js @@ -0,0 +1,193 @@ +require('module-alias/register'); +const { expect, assert } = require('chai'); +const rewire = require("rewire"); + +const { ApplicationState } = require("common"); +const state = new ApplicationState(); +state.updateState('READY'); + +const profileAPIModule = rewire("../../dist/api/profile.service"); + +class MockLogger { + constructor() { + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +class MockUsers { + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } + + async getUser() { + return { hederaAccountId: '123123' } + } +} + +class MockWallet { + async getKey() { + return {} + } +} + +class MockHederaSDKHelper { + async balance() { + return {} + } +} + +class MockDIDDocument { +} +MockDIDDocument.create = function () { + return { + getDid: function () { return {} } + } +} + +class MockDIDMessage { + setDocument() { } +} + +class MockMessageServer { + + setTopicObject() { + return { + sendMessage: function () { + return { + getId: () => 'test', + getTopicId: () => '123', + } + } + } + } +} + +class MockTopicHelper { + async create() { + return { + topicId: '' + } + } + async link() { } +} + +function getMongoRepositoryMock(entity) { + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + case 'DidDocument': + Object.assign(instance, { document: {} }); + return instance; + + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + return instance; + }, + update: async function (obj) { + return instance; + } + } +} + +const methods = { + 'GET_USER_BALANCE': function (...args) { + }, + 'CREATE_USER_PROFILE': function (...args) { + }, + 'set-did-document': function (...args) { + }, + 'set-vc-document': function (...args) { + }, + 'set-vp-document': function (...args) { + }, + 'get-vp-documents': function (...args) { + } +} + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + } +} + +profileAPIModule.__set__('users_1', { + Users: MockUsers, +}); +profileAPIModule.__set__('wallet_1', { + Wallet: MockWallet, + KeyType: { + KEY: 'key' + } +}); +profileAPIModule.__set__('_hedera_modules_1', { + HederaSDKHelper: MockHederaSDKHelper, + DIDDocument: MockDIDDocument, + DIDMessage: MockDIDMessage, + MessageServer: MockMessageServer, + MessageAction: { + CreateDID: 'CreateDID' + } +}); +profileAPIModule.__set__('logger_helper_1', { + Logger: MockLogger +}); +profileAPIModule.__set__('topicHelper_1', { + TopicHelper: MockTopicHelper +}); +profileAPIModule.__set__('typeorm_1', { + getMongoRepository: getMongoRepositoryMock +}); + +describe('Profile Service API', function () { + it('Get User Balance', async function () { + await profileAPIModule.profileAPI(channel); + const data = await methods['GET_USER_BALANCE']({ username: 'test' }); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) + + it('Create User Profile', async function () { + await profileAPIModule.profileAPI(channel); + const data = await methods['CREATE_USER_PROFILE']({}); + assert.equal(data.code, 200); + assert.equal(typeof data.body === 'object', true); + }) +}); diff --git a/guardian-service/tests/api/schema.service.test.js b/guardian-service/tests/api/schema.service.test.js new file mode 100644 index 0000000000..92d6a95377 --- /dev/null +++ b/guardian-service/tests/api/schema.service.test.js @@ -0,0 +1,138 @@ +require('module-alias/register'); +const rewire = require("rewire"); + +const schemaAPIModule = rewire("../../dist/api/schema.service"); +const topicHelperModule = rewire("../../dist/helpers/topicHelper.js") +const { ApplicationState } = require("common"); +const state = new ApplicationState(); +state.updateState('READY'); + +class MockLogger { + + constructor() { + console.log('Mock Logger'); + } + + setChannel() { } + getChannel() { } + + async info(message) { + console.log(message) + } + + async warn(message) { + console.warn(message) + } + + async error(message) { + console.warn(message) + } +} + +class MockUsers { + constructor() { + console.log('Mock Users'); + } + + async getHederaAccount() { + return { + hederaAccountId: '0.0.1548173', + hederaAccountKey: '302e020100300506032b657004220420e749aa65835ce90cab1cfb7f0fa11038e867e74946abca993f543cf9509c8edc', + did: 'did:hedera:testnet:Eyxtt46P5NGRoAJ1KdNaR6BP4PEbwDSDXpDncAApGpB3;hedera:testnet:fid=0.0.34052923', + } + } +} + +class TopicHelperMock { + constructor(...args) { + console.log('TopicHelper', args) + } +} + +function getMongoRepositoryMock(entity) { + console.log('name', entity.name); + + const instance = new entity; + + function responseConstructor() { + + switch (entity.name) { + case 'Topic': + return Object.assign(instance, { + topicId: "0.0.34228010", + name: "iRec Policy", + description: "iRec Policy", + owner: "did:hedera:testnet:9ZJXR58X9XQUgwiuxQQiTUt5yY2vX2Tw5Uph4xXsnkfM;hedera:testnet:tid=0.0.34194893", + type: "POLICY_TOPIC", + key: "302e020100300506032b657004220420abb61fea5149a3fc2ea64f851a8546f6d773fef29a0197f8300919168dbe0258", + policyId: "625d4f6d08f7f0692daad6a4", + policyUUID: "55ea39f6-4021-4c6d-8a75-dd24e1c7e0a5" + }) + + default: + return instance; + } + } + + return { + find: async function (filters) { + return [responseConstructor()] + }, + findOne: async function (filters) { + return responseConstructor() + }, + create: function (entity) { + return Object.assign(responseConstructor(), entity); + }, + save: async function (obj) { + console.log(obj); + return obj; + } + } +} + +const methods = { + 'CREATE_SCHEMA': function (...args) { + console.log(args); + } +} + +const channel = { + response: function (event, cb) { + methods[event] = async (...args) => { + return cb(...args) + } + }, + request: function (...args) { + console.log(args); + } +} + +const schemaRepository = { + find: async function () { + return ['schema'] + } +} + +describe('Schema Service API', function () { + before(async function () { + schemaAPIModule.__set__('users_1', { + Users: MockUsers, + }); + schemaAPIModule.__set__('logger_helper_1', { + Logger: MockLogger + }); + schemaAPIModule.__set__('typeorm_1', { + getMongoRepository: getMongoRepositoryMock + }); + topicHelperModule.__set__('typeorm_1', { + getMongoRepository: getMongoRepositoryMock + }); + schemaAPIModule.__set__('topicHelper_1', topicHelperModule); + }); + + // it('Create', async function() { + // schemaAPIModule.schemaAPI(channel, schemaRepository); + // methods['CREATE_SCHEMA'](); + // }); +}) diff --git a/guardian-service/tests/unit-tests/approve.test.js b/guardian-service/tests/unit-tests/approve.test.js index 609bbd7f69..8dab38230b 100644 --- a/guardian-service/tests/unit-tests/approve.test.js +++ b/guardian-service/tests/unit-tests/approve.test.js @@ -1,14 +1,14 @@ require('module-alias/register'); const { expect, assert } = require('chai'); -const { approveAPI } = require('./../../dist/api/approve.service'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); +const { approveAPI } = require('../../dist/api/approve.service'); +const { ApplicationState, ApplicationStates } = require('interfaces'); -const { - createChannel, - createTable, - checkMessage, - checkError +const { + createChannel, + createTable, + checkMessage, + checkError } = require('./helper'); describe('Approve service', function () { @@ -93,4 +93,4 @@ describe('Approve service', function () { field2: 'field2' }]); }); -}); \ No newline at end of file +}); diff --git a/guardian-service/tests/unit-tests/blocks/block-tree-generator.test.js b/guardian-service/tests/unit-tests/blocks/block-tree-generator.test.js index f3e29b5105..aa02999372 100644 --- a/guardian-service/tests/unit-tests/blocks/block-tree-generator.test.js +++ b/guardian-service/tests/unit-tests/blocks/block-tree-generator.test.js @@ -1,6 +1,13 @@ require('module-alias/register'); +const rewire = require("rewire"); + +const {Inject} = rewire('../../../dist/helpers/decorators/inject'); + +const { BlockTreeGenerator } = require("../../../dist/policy-engine/block-tree-generator"); describe('BlockTreeGenerator', function () { it('Create', async function () { + const generator = new BlockTreeGenerator(); + console.log(generator); }); }) diff --git a/guardian-service/tests/unit-tests/config.test.js b/guardian-service/tests/unit-tests/config.test.js index 4409e45a7e..db6594026f 100644 --- a/guardian-service/tests/unit-tests/config.test.js +++ b/guardian-service/tests/unit-tests/config.test.js @@ -1,12 +1,12 @@ const { expect, assert } = require('chai'); -const { configAPI } = require('./../../dist/api/config.service'); -const { - createChannel, - createTable, - checkMessage, - checkError +const { configAPI } = require('../../dist/api/config.service'); +const { + createChannel, + createTable, + checkMessage, + checkError } = require('./helper'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); +const { ApplicationState, ApplicationStates } = require('interfaces'); describe('Config service', function () { let service, channel, settingsRepository, topicRepository; @@ -38,7 +38,7 @@ describe('Config service', function () { }); it('Test UPDATE_SETTINGS', async function () { - + }); it('Test GET_SETTINGS', async function () { @@ -52,4 +52,4 @@ describe('Config service', function () { }); checkMessage(value, null); }); -}); \ No newline at end of file +}); diff --git a/guardian-service/tests/unit-tests/documents.test.js b/guardian-service/tests/unit-tests/documents.test.js index 04455e7550..bba006f84f 100644 --- a/guardian-service/tests/unit-tests/documents.test.js +++ b/guardian-service/tests/unit-tests/documents.test.js @@ -1,13 +1,13 @@ require("module-alias/register"); const { expect, assert } = require('chai'); -const { documentsAPI } = require('./../../dist/api/documents.service'); +const { documentsAPI } = require('../../dist/api/documents.service'); const { createChannel, createTable, checkMessage, checkError } = require('./helper'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); +const { ApplicationState, ApplicationStates } = require('interfaces'); describe('Documents service', function () { let channel; diff --git a/guardian-service/tests/unit-tests/dump/vc_document.js b/guardian-service/tests/unit-tests/dump/vc_document.js index 52a8501c3a..3d9a80a5da 100644 --- a/guardian-service/tests/unit-tests/dump/vc_document.js +++ b/guardian-service/tests/unit-tests/dump/vc_document.js @@ -769,4 +769,45 @@ module.exports.vc_document = [{ 'updateDate': { '$date': '2021-10-18T20:39:38.341Z' } +}, { + "_id": { + "$oid": "625ea9435714cda4463d8af2" + }, + "owner": "did:hedera:testnet:EeFHzwywzQuMWtn8LNEdLE1RnZD2t4DsPnDjuasdrQjs;hedera:testnet:tid=0.0.34235318", + "hash": "9s7b1eW2gkZEd64SAidCci3UmXQgfZt2w6ajiKdPdHa9", + "document": { + "id": "81e6593a-a9b5-4017-b081-5b714554aa0b", + "type": ["VerifiableCredential"], + "issuer": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373", + "issuanceDate": "2022-04-19T12:21:18.189Z", + "@context": ["https://www.w3.org/2018/credentials/v1"], + "credentialSubject": [{ + "date": "2022-04-19T12:21:18.185Z", + "tokenId": "0.0.34235376", + "amount": "1", + "@context": ["https://ipfs.io/ipfs/bafkreiaamzhmh3l5pn5nneib5yifb3gjwlotf6fr6vb65j7tfi4tefxcza"], + "type": "MintToken&1.0.0" + }], + "proof": { + "type": "Ed25519Signature2018", + "created": "2022-04-19T12:21:18Z", + "verificationMethod": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373#did-root-key", + "proofPurpose": "assertionMethod", + "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..FiEHhQu_ILgimHiuBMzB5t2-Az-g9ogHCgogBtYcQF4IG5J3ZTKlYMU9RMyH8IyQF6UG3DnJ3t6Ba05gFfJoCw" + } + }, + "type": "mint", + "policyId": "625ea4eb5714cda4463d8ae1", + "tag": "mintToken", + "schema": "#MintToken&1.0.0", + "messageId": "1650370882.370492000", + "hederaStatus": "NEW", + "signature": 0, + "option": {}, + "createDate": { + "$date": "2022-04-19T12:21:23.809Z" + }, + "updateDate": { + "$date": "2022-04-19T12:21:23.809Z" + } }]; \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/did-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/did-message.test.js new file mode 100644 index 0000000000..9ae8ba1c9d --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/did-message.test.js @@ -0,0 +1,54 @@ +const { expect, assert } = require('chai'); + +const { + DIDMessage +} = require('../../../../dist/hedera-modules/message/did-message'); + +const { + DIDDocument +} = require('../../../../dist/hedera-modules/vcjs/did-document'); + +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); + +describe('DIDMessage', function () { + const testDidMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.DIDDocument, + action: MessageAction.CreateDID, + did: "testDid", + cid: "testCid", + url: "testUrl" + }; + const testDocumentObject = JSON.stringify({ + name: "testDocumentName" + }); + + it('Test DIDMessage', async function () { + assert.throws(DIDMessage.fromMessage); + assert.throws(DIDMessage.fromMessageObject); + + const testDidDocument = DIDDocument.create(); + const didMessage = new DIDMessage(MessageAction.CreateDID); + assert.exists(didMessage); + didMessage.setDocument(testDidDocument); + assert.deepEqual(didMessage.getDocument(), testDidDocument.getDocument()); + assert.equal((await didMessage.toDocuments()).toString(), JSON.stringify(testDidDocument.getDocument())) + assert.isTrue(didMessage.validate()) + + didMessage.loadDocuments([testDocumentObject]); + assert.exists(didMessage.toDocuments()); + + const didMessageByTestMessage = DIDMessage.fromMessageObject(testDidMessage); + assert.exists(didMessageByTestMessage); + assert.deepEqual(didMessageByTestMessage.getUrl(), { cid: testDidMessage.cid, url: testDidMessage.url }); + assert.exists(didMessageByTestMessage.toMessageObject()); + + const didMessageByTestJson = DIDMessage.fromMessage(JSON.stringify(testDidMessage)); + assert.exists(didMessageByTestJson); + assert.deepEqual(didMessageByTestJson.getUrl(), { cid: testDidMessage.cid, url: testDidMessage.url }); + assert.exists(didMessageByTestMessage.toMessageObject()); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/message.test.js new file mode 100644 index 0000000000..c983dd4b79 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/message.test.js @@ -0,0 +1,41 @@ +const { expect, assert } = require('chai'); + +const { + Message +} = require('../../../../dist/hedera-modules/message/message'); + +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { UrlType } = require('../../../../dist/hedera-modules/message/url.interface'); + +describe('Message', function () { + + const testUrls = [{ + cid: "testCidFirst", + url: "testUrlFirst" + }, { + cid: "testCidSecond", + url: "testUrlSecond" + }]; + const testId = "testId"; + const topicId = "testTopicId"; + + it('Test Message', async function () { + const message = new Message(MessageAction.CreateDID, MessageType.DIDDocument); + assert.equal(message.responseType, "str"); + message.setUrls(testUrls); + assert.deepEqual(message.getUrls(), testUrls); + message.setId(testId); + assert.equal(message.getId(), testId); + message.setTopicId(topicId); + assert.equal(message.getTopicId(), topicId); + assert.equal(message.getUrlValue(0), testUrls[0].url); + assert.equal(message.getUrlValue(0, UrlType.cid), testUrls[0].cid); + message.revoke(); + + const messageToMessage = JSON.parse(message.toMessage()); + assert.exists(messageToMessage); + assert.equal(messageToMessage.status, MessageStatus.REVOKE); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/policy-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/policy-message.test.js new file mode 100644 index 0000000000..b173397a6d --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/policy-message.test.js @@ -0,0 +1,59 @@ +const { expect, assert } = require('chai'); + +const { + PolicyMessage +} = require('../../../../dist/hedera-modules/message/policy-message'); + +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); +const { UrlType } = require('../../../../dist/hedera-modules/message/url.interface'); + +describe('PolicyMessage', function () { + + const testPolicyMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.Policy, + action: MessageAction.CreatePolicy, + uuid: "testUUID", + name: "testName", + description: "testDescription", + topicDescription: "testTopicDescription", + version: "testVersion", + policyTag: "testPolicyTag", + owner: "testOwner", + topicId: "testTopicId", + instanceTopicId: "testInstanceTopicId", + cid: "testCID", + url: "testURL" + }; + const testDocumentObject = JSON.stringify({ + name: "testDocumentName" + }); + + it('Test PolicyMessage', async function () { + assert.throws(PolicyMessage.fromMessageObject); + assert.throws(PolicyMessage.fromMessage); + + const policyMessage = new PolicyMessage(MessageType.Policy, MessageAction.CreatePolicy); + policyMessage.setDocument(testPolicyMessage, null); + assert.isNull(policyMessage.getDocument()) + + policyMessage.loadDocuments([testDocumentObject]); + assert.exists(policyMessage.toDocuments()); + assert.isTrue(policyMessage.validate()) + + const policyMessageByTestMessage = PolicyMessage.fromMessageObject(testPolicyMessage); + assert.exists(policyMessageByTestMessage); + assert.deepEqual(policyMessageByTestMessage.getUrl(), { cid: testPolicyMessage.cid, url: testPolicyMessage.url }); + assert.equal(policyMessageByTestMessage.getDocumentUrl(UrlType.cid), testPolicyMessage.cid); + assert.equal(policyMessageByTestMessage.getDocumentUrl(), testPolicyMessage.url); + + const policyMessageByTestJSON = PolicyMessage.fromMessage(JSON.stringify(testPolicyMessage)); + assert.exists(policyMessageByTestJSON); + assert.deepEqual(policyMessageByTestJSON.getUrl(), { cid: testPolicyMessage.cid, url: testPolicyMessage.url }); + assert.equal(policyMessageByTestJSON.getDocumentUrl(UrlType.cid), testPolicyMessage.cid); + assert.equal(policyMessageByTestJSON.getDocumentUrl(), testPolicyMessage.url); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/schema-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/schema-message.test.js new file mode 100644 index 0000000000..9ffa41ca5b --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/schema-message.test.js @@ -0,0 +1,73 @@ +const { expect, assert } = require('chai'); + +const { + SchemaMessage +} = require('../../../../dist/hedera-modules/message/schema-message'); +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); +const { UrlType } = require('../../../../dist/hedera-modules/message/url.interface'); + +describe('SchemaMessage', function () { + + const testSchemaMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.Schema, + action: MessageAction.CreateSchema, + name: "testName", + description: "testDescription", + entity: "testEntity", + owner: "testOwner", + uuid: "testUUID", + version: "testVersion", + document_cid: "testDocumentCID", + document_url: "testDocumentURL", + context_cid: "testContextCID", + context_url: "testContextURL" + }; + const testDocument = "testDocument"; + const testContext = "testContext"; + const testDocumentObject = JSON.stringify({ + name: "testDocumentName" + }); + + it('Test SchemaMessage', async function () { + assert.throws(SchemaMessage.fromMessageObject); + assert.throws(SchemaMessage.fromMessage); + + const schemaMessage = new SchemaMessage(MessageAction.CreateSchema); + assert.exists(schemaMessage); + + schemaMessage.setDocument({ ...testSchemaMessage, document: testDocument, context: testContext}); + assert.equal(schemaMessage.getDocument(), testDocument); + assert.equal(schemaMessage.getContext(), testContext); + assert.exists(schemaMessage.toDocuments()); + assert.isTrue(schemaMessage.validate()); + + schemaMessage.loadDocuments([testDocumentObject]); + assert.exists(schemaMessage.toDocuments()); + + const schemaMessageByTestMessage = SchemaMessage.fromMessageObject(testSchemaMessage); + assert.exists(schemaMessageByTestMessage); + assert.deepEqual(schemaMessageByTestMessage.getUrl(), [{ + cid: testSchemaMessage.document_cid, url: testSchemaMessage.document_url + }, { + cid: testSchemaMessage.context_cid, url: testSchemaMessage.context_url + }]); + assert.equal(schemaMessageByTestMessage.getDocumentUrl(UrlType.cid), testSchemaMessage.document_cid); + assert.equal(schemaMessageByTestMessage.getDocumentUrl(), testSchemaMessage.document_url); + assert.exists(schemaMessageByTestMessage.toMessageObject()); + + const schemaMessageByTestJSON = SchemaMessage.fromMessage(JSON.stringify(testSchemaMessage)); + assert.exists(schemaMessageByTestJSON); + assert.deepEqual(schemaMessageByTestJSON.getUrl(), [{ + cid: testSchemaMessage.document_cid, url: testSchemaMessage.document_url + }, { + cid: testSchemaMessage.context_cid, url: testSchemaMessage.context_url + }]); + assert.equal(schemaMessageByTestJSON.getDocumentUrl(UrlType.cid), testSchemaMessage.document_cid); + assert.equal(schemaMessageByTestJSON.getDocumentUrl(), testSchemaMessage.document_url); + assert.exists(schemaMessageByTestJSON.toMessageObject()); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/topic-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/topic-message.test.js new file mode 100644 index 0000000000..0e45206173 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/topic-message.test.js @@ -0,0 +1,45 @@ +const { expect, assert } = require('chai'); + +const { + TopicMessage +} = require('../../../../dist/hedera-modules/message/topic-message'); +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); + +describe('TopicMessage', function () { + + const testTopicMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.Topic, + action: MessageAction.CreateSchema, + name: "testName", + description: "testDescription", + owner: "testOwner", + messageType: "testMessageType", + childId: "testChildId", + parentId: "testParentId", + rationale: "testRationale" + } + + it('Test TopicMessage', async function () { + assert.throws(TopicMessage.fromMessageObject); + assert.throws(TopicMessage.fromMessage); + + const topicMessage = new TopicMessage(MessageAction.CreateTopic); + assert.exists(topicMessage); + + topicMessage.setDocument(testTopicMessage); + assert.hasAllKeys(topicMessage.toMessageObject(), Object.keys(testTopicMessage)); + assert.isTrue(topicMessage.validate()); + + const topicMessageByTestMessage = TopicMessage.fromMessageObject(testTopicMessage); + assert.exists(topicMessageByTestMessage); + assert.deepEqual(topicMessageByTestMessage.getUrl(), []); + + const topicMessageByTestJSON = TopicMessage.fromMessage(JSON.stringify(testTopicMessage)); + assert.exists(topicMessageByTestJSON); + assert.deepEqual(topicMessageByTestMessage.getUrl(), []); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/vc-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/vc-message.test.js new file mode 100644 index 0000000000..e9c124233e --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/vc-message.test.js @@ -0,0 +1,65 @@ +const { expect, assert } = require('chai'); + +const { + VCMessage +} = require('../../../../dist/hedera-modules/message/vc-message'); +const { + VcDocument +} = require('../../../../dist/hedera-modules/vcjs/vc-document'); +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); +const { UrlType } = require('../../../../dist/hedera-modules/message/url.interface'); +const { vc_document } = require('../../dump/vc_document'); + +describe('VCMessage', function () { + + const testVCMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.VCDocumnet, + action: MessageAction.CreateVC, + issuer: "testIssuer", + cid: "testCID", + url: "testCID", + relationships: ["testRelation1", "testRelation2", "testRelation3"] + }; + const testDocumentObject = JSON.stringify({ + name: "testDocumentName" + }); + + it('Test VCMessage', async function () { + assert.throws(VCMessage.fromMessageObject); + assert.throws(VCMessage.fromMessage); + + const vcMessage = new VCMessage(MessageAction.CreateVC); + assert.exists(vcMessage); + + const testVcDocument = VcDocument.fromJsonTree(vc_document[0].document); + vcMessage.setDocument(testVcDocument); + assert.deepEqual(vcMessage.getDocument(), testVcDocument.getDocument()); + assert.exists(vcMessage.toDocuments()); + + vcMessage.loadDocuments([testDocumentObject]); + assert.exists(vcMessage.toDocuments()); + assert.isTrue(vcMessage.validate()); + + const vcMessageByTestMessage = VCMessage.fromMessageObject(testVCMessage); + assert.exists(vcMessageByTestMessage); + assert.deepEqual(vcMessageByTestMessage.getUrl(), { + cid: testVCMessage.cid, url: testVCMessage.url + }); + assert.equal(vcMessageByTestMessage.getDocumentUrl(UrlType.cid), testVCMessage.cid); + assert.equal(vcMessageByTestMessage.getDocumentUrl(), testVCMessage.url); + assert.exists(vcMessageByTestMessage.toMessageObject()); + + const vcMessageByTestJSON = VCMessage.fromMessage(JSON.stringify(testVCMessage)); + assert.exists(vcMessageByTestJSON); + assert.deepEqual(vcMessageByTestJSON.getUrl(), { + cid: testVCMessage.cid, url: testVCMessage.url + }); + assert.equal(vcMessageByTestJSON.getDocumentUrl(UrlType.cid), testVCMessage.cid); + assert.equal(vcMessageByTestJSON.getDocumentUrl(), testVCMessage.url); + assert.exists(vcMessageByTestJSON.toMessageObject()); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/message/vp-message.test.js b/guardian-service/tests/unit-tests/hedera-modules/message/vp-message.test.js new file mode 100644 index 0000000000..a66b96b8fc --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/message/vp-message.test.js @@ -0,0 +1,65 @@ +const { expect, assert } = require('chai'); + +const { + VPMessage +} = require('../../../../dist/hedera-modules/message/vp-message'); +const { + VpDocument +} = require('../../../../dist/hedera-modules/vcjs/vp-document'); +const { MessageStatus } = require('../../../../dist/hedera-modules/message/message'); +const { MessageType } = require('../../../../dist/hedera-modules/message/message-type'); +const { MessageAction } = require('../../../../dist/hedera-modules/message/message-action'); +const { UrlType } = require('../../../../dist/hedera-modules/message/url.interface'); +const { vp_document } = require('../../dump/vp_document'); + +describe('VPMessage', function () { + + const testVPMessage = { + id: "testId", + status: MessageStatus.ISSUE, + type: MessageType.VPDocumnet, + action: MessageAction.CreateVP, + issuer: "testIssuer", + cid: "testCID", + url: "testCID", + relationships: ["testRelation1", "testRelation2", "testRelation3"] + }; + const testDocumentObject = JSON.stringify({ + name: "testDocumentName" + }); + + it('Test VPMessage', async function () { + assert.throws(VPMessage.fromMessageObject); + assert.throws(VPMessage.fromMessage); + + const vpMessage = new VPMessage(MessageAction.CreateVP); + assert.exists(vpMessage); + + const testVpDocument = VpDocument.fromJsonTree(vp_document[0].document); + vpMessage.setDocument(testVpDocument); + assert.deepEqual(vpMessage.getDocument(), testVpDocument.getDocument()); + assert.exists(vpMessage.toDocuments()); + + vpMessage.loadDocuments([testDocumentObject]); + assert.exists(vpMessage.toDocuments()); + assert.isTrue(vpMessage.validate()); + + const vpMessageByTestMessage = VPMessage.fromMessageObject(testVPMessage); + assert.exists(vpMessageByTestMessage); + assert.deepEqual(vpMessageByTestMessage.getUrl(), { + cid: testVPMessage.cid, url: testVPMessage.url + }); + assert.equal(vpMessageByTestMessage.getDocumentUrl(UrlType.cid), testVPMessage.cid); + assert.equal(vpMessageByTestMessage.getDocumentUrl(), testVPMessage.url); + assert.exists(vpMessageByTestMessage.toMessageObject()); + + const vpMessageByTestJSON = VPMessage.fromMessage(JSON.stringify(testVPMessage)); + assert.exists(vpMessageByTestJSON); + assert.deepEqual(vpMessageByTestJSON.getUrl(), { + cid: testVPMessage.cid, url: testVPMessage.url + }); + assert.equal(vpMessageByTestJSON.getDocumentUrl(UrlType.cid), testVPMessage.cid); + assert.equal(vpMessageByTestJSON.getDocumentUrl(), testVPMessage.url); + assert.exists(vpMessageByTestJSON.toMessageObject()); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/did-document.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/did-document.test.js new file mode 100644 index 0000000000..ae9399260e --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/did-document.test.js @@ -0,0 +1,131 @@ +const { expect, assert } = require('chai'); + +const { + DidRootKey, + DIDDocument, + DidDocumentBase +} = require('../../../../dist/hedera-modules/vcjs/did-document'); + +const { PrivateKey } = require("@hashgraph/sdk"); +const { did_document } = require('../../dump/did_document'); + +describe('DidDocuments', function () { + const topicId = "0.0.34195177"; + const did = `did:hedera:testnet:4TxrFRUL3zxz5tMb9ioZEzhDq6h3QBijWAFbPWC7mXFv;hedera:testnet:tid=${topicId}`; + const newPrivateKey = PrivateKey.generate(); + + it('Test DidRootKey', async function () { + assert.throw(DidRootKey.createByPublicKey); + assert.throw(DidRootKey.createByPublicKey.bind(did)); + assert.throw(DidRootKey.createByPrivateKey); + assert.throw(DidRootKey.createByPrivateKey.bind(did)); + assert.throw(DidRootKey.create); + assert.throw(DidRootKey.fromJsonTree); + assert.throw(DidRootKey.fromJson); + + const didRootKeyWithoutKeys = DidRootKey.create(did); + assert.exists(didRootKeyWithoutKeys); + assert.equal(didRootKeyWithoutKeys.getMethod(), DidRootKey.DID_ROOT_KEY_NAME); + assert.equal(didRootKeyWithoutKeys.getId(), did + DidRootKey.DID_ROOT_KEY_NAME); + assert.equal(didRootKeyWithoutKeys.getType(), DidRootKey.DID_ROOT_KEY_TYPE); + assert.equal(didRootKeyWithoutKeys.getController(), did); + assert.isNull(didRootKeyWithoutKeys.getPublicKey()); + assert.isNull(didRootKeyWithoutKeys.getPublicKeyBase58()) + assert.isNull(didRootKeyWithoutKeys.getPrivateKey()); + assert.isNull(didRootKeyWithoutKeys.getPrivateKeyBase58()); + + const didRootKeyCreatedByPublicKey = DidRootKey.createByPublicKey(did, newPrivateKey.publicKey); + assert.exists(didRootKeyCreatedByPublicKey); + assert.equal(didRootKeyCreatedByPublicKey.getId(), did + DidRootKey.DID_ROOT_KEY_NAME); + assert.equal(didRootKeyCreatedByPublicKey.getType(), DidRootKey.DID_ROOT_KEY_TYPE); + assert.equal(didRootKeyCreatedByPublicKey.getController(), did); + assert.deepEqual(didRootKeyCreatedByPublicKey.getPublicKey(), newPrivateKey.publicKey); + assert.isString(didRootKeyCreatedByPublicKey.getPublicKeyBase58()) + assert.isNull(didRootKeyCreatedByPublicKey.getPrivateKey()); + assert.isNull(didRootKeyCreatedByPublicKey.getPrivateKeyBase58()); + + const didRootKeyCreatedByPrivateKey = DidRootKey.createByPrivateKey(did, newPrivateKey); + assert.exists(didRootKeyCreatedByPrivateKey); + assert.equal(didRootKeyCreatedByPrivateKey.getId(), did + DidRootKey.DID_ROOT_KEY_NAME); + assert.equal(didRootKeyCreatedByPrivateKey.getType(), DidRootKey.DID_ROOT_KEY_TYPE); + assert.equal(didRootKeyCreatedByPrivateKey.getController(), did); + assert.deepEqual(didRootKeyCreatedByPrivateKey.getPublicKey(), newPrivateKey.publicKey); + assert.isString(didRootKeyCreatedByPrivateKey.getPublicKeyBase58()) + assert.deepEqual(didRootKeyCreatedByPrivateKey.getPrivateKey(), newPrivateKey); + assert.isString(didRootKeyCreatedByPrivateKey.getPrivateKeyBase58()); + + const verificationMethod = did_document[0].document.verificationMethod[0]; + const didRootKeyFromJsonTree = DidRootKey.fromJsonTree(verificationMethod); + assert.exists(didRootKeyFromJsonTree); + assert.deepEqual(didRootKeyFromJsonTree.getVerificationMethod(), verificationMethod); + assert.hasAllKeys(didRootKeyFromJsonTree.getPrivateVerificationMethod(), ['id', 'type', 'controller', 'publicKeyBase58', 'privateKeyBase58']); + assert.deepEqual(didRootKeyFromJsonTree.toJsonTree(), verificationMethod); + + const verificationMethodJson = JSON.stringify(verificationMethod); + const didRootKeyFromJson = DidRootKey.fromJson(verificationMethodJson); + assert.deepEqual(didRootKeyFromJson.getVerificationMethod(), verificationMethod); + assert.hasAllKeys(didRootKeyFromJson.getPrivateVerificationMethod(), ['id', 'type', 'controller', 'publicKeyBase58', 'privateKeyBase58']); + assert.equal(didRootKeyFromJson.toJson(), verificationMethodJson); + }); + + it('Test DidDocumentBase', async function () { + assert.throw(DidDocumentBase.createByPrivateKey); + assert.throw(DidDocumentBase.createByPrivateKey.bind(did)); + assert.throw(DidDocumentBase.createByPublicKey); + assert.throw(DidDocumentBase.createByPublicKey.bind(did)); + + assert.deepEqual(new DidDocumentBase().getContext(), [ + DidDocumentBase.DID_DOCUMENT_CONTEXT, + DidDocumentBase.DID_DOCUMENT_TRANSMUTE_CONTEXT + ]); + + const didDocumentBaseCreatedByPrivateKey = DidDocumentBase.createByPrivateKey(did, newPrivateKey); + assert.exists(didDocumentBaseCreatedByPrivateKey); + assert.hasAllKeys(didDocumentBaseCreatedByPrivateKey.getPrivateDidDocument(), [ + DidDocumentBase.CONTEXT, + DidDocumentBase.ID, + DidDocumentBase.VERIFICATION_METHOD, + DidDocumentBase.AUTHENTICATION, + DidDocumentBase.ASSERTION_METHOD + ]); + assert.equal(didDocumentBaseCreatedByPrivateKey.getId(), did); + + const didDocumentBaseCreatedByPublicKey = DidDocumentBase.createByPublicKey(did, newPrivateKey.publicKey); + assert.exists(didDocumentBaseCreatedByPublicKey); + assert.hasAllKeys(didDocumentBaseCreatedByPublicKey.getDidDocument(), [ + DidDocumentBase.CONTEXT, + DidDocumentBase.ID, + DidDocumentBase.VERIFICATION_METHOD, + DidDocumentBase.AUTHENTICATION, + DidDocumentBase.ASSERTION_METHOD + ]); + assert.equal(didDocumentBaseCreatedByPublicKey.getId(), did); + }); + + it('Test DIDDocument', async function () { + assert.throw(DIDDocument.from); + assert.throw(DIDDocument.from.bind(did)); + + const createdDidDocument = DIDDocument.create(newPrivateKey, topicId); + assert.exists(createdDidDocument); + assert.equal(createdDidDocument.getMethod(), DIDDocument.HEDERA_HCS); + assert.isString(createdDidDocument.buildDid()); + assert.deepEqual(createdDidDocument.getPublicKey(), newPrivateKey.publicKey); + assert.isString(createdDidDocument.getPrivateKeyString()); + assert.deepEqual(createdDidDocument.getPrivateKey(), newPrivateKey); + assert.isString(createdDidDocument.getPublicKeyString()); + assert.equal(createdDidDocument.getDidTopicId(), topicId); + assert.isString(createdDidDocument.toString()); + assert.isString(createdDidDocument.getDid()); + assert.exists(createdDidDocument.getDocument()); + + const createdDidDocumentFromTestDid = DIDDocument.from(createdDidDocument.buildDid(), createdDidDocument.getPublicKeyString()); + assert.exists(createdDidDocumentFromTestDid); + assert.equal(createdDidDocumentFromTestDid.getMethod(), DIDDocument.HEDERA_HCS); + assert.equal(createdDidDocumentFromTestDid.getPublicKeyString(), createdDidDocument.getPublicKeyString()); + assert.deepEqual(createdDidDocumentFromTestDid.getDidTopicId(), createdDidDocument.getDidTopicId()); + assert.equal(createdDidDocumentFromTestDid.toString(), createdDidDocument.toString()); + assert.equal(createdDidDocumentFromTestDid.getDid(), createdDidDocument.getDid()); + assert.exists(createdDidDocumentFromTestDid.getDocument()); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/issuer.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/issuer.test.js new file mode 100644 index 0000000000..ec75e63164 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/issuer.test.js @@ -0,0 +1,30 @@ +const { expect, assert } = require('chai'); + +const { + Issuer +} = require('../../../../dist/hedera-modules/vcjs/issuer'); + +describe('Issuer', function () { + const rootObj = { + id: "testId", + name: "testName" + }; + + it('Test Issuer', async function () { + const testIssuer = new Issuer(rootObj.id, rootObj.name); + assert.equal(testIssuer.getId(), rootObj.id); + assert.equal(testIssuer.getName(), rootObj.name); + + assert.throws(Issuer.fromJson); + assert.throws(Issuer.fromJsonTree); + + const issuer = Issuer.fromJsonTree(rootObj); + assert.equal(issuer.getId(), rootObj.id); + assert.equal(issuer.getName(), rootObj.name); + assert.deepEqual(issuer.toJsonTree(), rootObj); + + const rootJSON = JSON.stringify(rootObj); + assert.equal(issuer.toJSON(), rootJSON); + assert.deepEqual(Issuer.fromJson(rootJSON), issuer); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-document.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-document.test.js new file mode 100644 index 0000000000..66f8593eb5 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-document.test.js @@ -0,0 +1,69 @@ +const { expect, assert } = require('chai'); + +const { + VcDocument +} = require('../../../../dist/hedera-modules/vcjs/vc-document'); +const { + VcSubject +} = require('../../../../dist/hedera-modules/vcjs/vc-subject'); +const { vc_document } = require('../../dump/vc_document'); +const { + Issuer +} = require('../../../../dist/hedera-modules/vcjs/issuer'); + +describe('VcDocument', function () { + + const testVcDocument = vc_document[0].document; + const testType = "testType"; + const testContext = "testContext"; + const testVcDocumentSecond = vc_document[1].document; + const testCS = testVcDocumentSecond.credentialSubject[0]; + const testCSs = testVcDocumentSecond.credentialSubject; + const testIssuerSecond = testVcDocumentSecond.issuer; + + it('Test VcDocument', async function () { + const emptyVc = new VcDocument(); + assert.deepEqual(emptyVc.getContext(), [VcDocument.FIRST_CONTEXT_ENTRY]); + assert.deepEqual(emptyVc.getType(), [VcDocument.VERIFIABLE_CREDENTIAL_TYPE]); + + assert.throws(VcDocument.fromJsonTree); + assert.throws(VcDocument.fromJson); + + const testIssuer = new Issuer(testVcDocument.issuer); + const vcDocument = VcDocument.fromJsonTree(testVcDocument); + assert.equal(vcDocument.getId(), testVcDocument.id); + assert.deepEqual(vcDocument.getContext(), testVcDocument['@context']); + assert.deepEqual(vcDocument.getIssuer(), testIssuer); + assert.deepEqual(vcDocument.getIssuerDid(), testIssuer.getId()); + assert.deepEqual(vcDocument.getIssuanceDate().toDate().getTime(), new Date(testVcDocument.issuanceDate).getTime()); + assert.equal(vcDocument.getSubjectType(), testVcDocument.credentialSubject[0].type); + assert.equal(vcDocument.length, testVcDocument.credentialSubject.length); + assert.isString(vcDocument.toCredentialHash()); + assert.exists(vcDocument); + assert.deepEqual(vcDocument.toJsonTree(), testVcDocument); + assert.deepEqual(vcDocument.getDocument(), testVcDocument); + assert.deepEqual(JSON.parse(vcDocument.toJson()), testVcDocument); + + testVcDocument.issuer = testIssuerSecond; + vcDocument.setIssuer(Issuer.fromJsonTree(testIssuerSecond)); + assert.deepEqual(vcDocument.getIssuer(), Issuer.fromJsonTree(testIssuer)); + + testVcDocument['@context'].push(testContext); + vcDocument.addContext(testContext); + assert.deepEqual(vcDocument.getContext(), testVcDocument['@context']); + + testVcDocument.type.push(testType); + vcDocument.addType(testType); + assert.deepEqual(vcDocument.getType(), testVcDocument.type); + + testVcDocument.proof = vc_document[1].document.proof; + vcDocument.setProof(testVcDocument.proof); + assert.deepEqual(vcDocument.getProof(), testVcDocument.proof); + + testVcDocument.credentialSubject.push(testCS); + vcDocument.addCredentialSubject(VcSubject.fromJsonTree(testCS)); + testVcDocument.credentialSubject.push(...testCSs); + vcDocument.addCredentialSubjects(testCSs.map((testCS) => VcSubject.fromJsonTree(testCS))); + assert.deepEqual(vcDocument.toJsonTree(), testVcDocument); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-subject.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-subject.test.js new file mode 100644 index 0000000000..c754bd3143 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-subject.test.js @@ -0,0 +1,29 @@ +const { expect, assert } = require('chai'); + +const { + VcSubject +} = require('../../../../dist/hedera-modules/vcjs/vc-subject'); +const { vc_document } = require('../../dump/vc_document'); + +describe('VcSubject', function () { + const testCS = vc_document[0].document.credentialSubject[0]; + + it('Test VcSubject', async function () { + assert.throws(VcSubject.fromJsonTree); + assert.throws(VcSubject.create); + + const vcSubject = VcSubject.fromJsonTree(testCS); + assert.equal(vcSubject.getId(), testCS.id); + assert.equal(vcSubject.getType(), testCS.type); + assert.equal(vcSubject.getField("name"), testCS.name); + + const testContext = "testContext"; + vcSubject.addContext(testContext); + testCS['@context'].push(testContext); + assert.deepEqual(vcSubject.toJsonTree(), testCS); + + assert.deepEqual(JSON.parse(VcSubject.fromJson(JSON.stringify(testCS)).toJson()), testCS); + + assert.deepEqual(VcSubject.create(testCS).toJsonTree(), testCS); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/vcjs.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vcjs.test.js new file mode 100644 index 0000000000..727a85adb4 --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vcjs.test.js @@ -0,0 +1,557 @@ +const { expect, assert } = require('chai'); + +const { + VCJS +} = require('../../../../dist/hedera-modules/vcjs/vcjs'); +const { + DefaultDocumentLoader +} = require('../../../../dist/hedera-modules/document-loader/document-loader-default'); +const { + ContextDocumentLoader +} = require('../../../../dist/document-loader/context-loader'); +const { + DIDDocumentLoader +} = require('../../../../dist/document-loader/did-document-loader'); +const { + VCSchemaLoader +} = require('../../../../dist/document-loader/vc-schema-loader'); +const { + SubjectSchemaLoader +} = require('../../../../dist/document-loader/subject-schema-loader'); +const { + DIDDocument +} = require('../../../../dist/hedera-modules/vcjs/did-document'); +const { PrivateKey } = require("@hashgraph/sdk"); + +const { vc_document } = require('../../dump/vc_document'); + + +describe('VCJS', function () { + const actualVcDocument = vc_document.find(document => document.hash === '9s7b1eW2gkZEd64SAidCci3UmXQgfZt2w6ajiKdPdHa9'); + const vcValueToCreate = actualVcDocument.document.credentialSubject[0]; + const newPrivateKey = PrivateKey.generate(); + const schema = { + "_id": { + "$oid": "625e95e75714cda4463d8aaa" + }, + "uuid": "MintToken", + "hash": "", + "name": "MintToken", + "entity": "MINT_TOKEN", + "status": "PUBLISHED", + "readonly": true, + "document": { + "$id": "#MintToken&1.0.0", + "$comment": "{ \"term\": \"MintToken&1.0.0\", \"@id\": \"undefined#MintToken&1.0.0\" }", + "title": "MintToken", + "description": "MintToken", + "type": "object", + "properties": { + "@context": { + "oneOf": [{ + "type": "string" + }, { + "type": "array", + "items": { + "type": "string" + } + }], + "readOnly": true + }, + "type": { + "oneOf": [{ + "type": "string" + }, { + "type": "array", + "items": { + "type": "string" + } + }], + "readOnly": true + }, + "id": { + "type": "string", + "readOnly": true + }, + "date": { + "$comment": "{\"term\": \"date\", \"@id\": \"https://www.schema.org/text\"}", + "title": "date", + "description": "date", + "type": "string", + "readOnly": false + }, + "amount": { + "$comment": "{\"term\": \"amount\", \"@id\": \"https://www.schema.org/text\"}", + "title": "amount", + "description": "amount", + "type": "string", + "readOnly": false + }, + "tokenId": { + "$comment": "{\"term\": \"tokenId\", \"@id\": \"https://www.schema.org/text\"}", + "title": "tokenId", + "description": "tokenId", + "type": "string", + "readOnly": false + } + }, + "required": ["date", "amount", "tokenId"], + "additionalProperties": false + }, + "context": { + "@context": { + "@version": 1.1, + "@vocab": "https://w3id.org/traceability/#undefinedTerm", + "id": "@id", + "type": "@type", + "MintToken&1.0.0": { + "@id": "undefined#MintToken&1.0.0", + "@context": { + "date": { + "@id": "https://www.schema.org/text" + }, + "amount": { + "@id": "https://www.schema.org/text" + }, + "tokenId": { + "@id": "https://www.schema.org/text" + } + } + } + } + }, + "version": "1.0.0", + "creator": null, + "owner": null, + "topicId": "0.0.29614911", + "messageId": "1648050464.170190891", + "documentURL": "https://ipfs.io/ipfs/bafkreiflfkyh4fhft7yyrq7g7rnvqwac3mengo555vlz72qtsnqmhcy77q", + "contextURL": "https://ipfs.io/ipfs/bafkreiaamzhmh3l5pn5nneib5yifb3gjwlotf6fr6vb65j7tfi4tefxcza", + "iri": "#MintToken&1.0.0", + "createDate": { + "$date": "2022-04-19T10:58:47.545Z" + } + } + + class TestVCSchemaLoader extends VCSchemaLoader { + loadSchemaContexts(context) { + return typeof context == 'string' ? schema : [schema]; + } + } + + class TestContextDocumentLoader extends ContextDocumentLoader { + loadSchemaContext(context) { + return schema; + } + } + + class TestSubjectSchemaLoader extends SubjectSchemaLoader { + loadSchemaContexts(context) { + return typeof context == 'string' ? schema : [schema]; + } + } + + class TestDIDDocumentLoader extends DIDDocumentLoader { + getDocument(iri) { + return { + "@context": ["https://www.w3.org/ns/did/v1", "https://ns.did.ai/transmute/v1"], + "id": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373", + "verificationMethod": [{ + "id": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373#did-root-key", + "type": "Ed25519VerificationKey2018", + "controller": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373", + "publicKeyBase58": "7KtohV6cu3ZDXZnbc3QyPXYYHJUXJg5PoE9T7V4cV7wd" + }], + "authentication": "did:hedera:testnet:L8wzF8StAHSQ2yza6RPpCKWFUSXg5CyXZCb4QZtGtWq;hedera:testnet:tid=0.0.34235373#did-root-key", + "assertionMethod": ["#did-root-key"] + } + } + } + + class TestDefaultDocumentLoader extends DefaultDocumentLoader { + has(iri) { + return iri === 'https://www.w3.org/2018/credentials/v1' + || iri === 'https://www.w3.org/ns/did/v1' + || iri === 'https://ns.did.ai/transmute/v1' + } + get(iri) { + const credentials = { + documentUrl: iri, + document: { + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "credentialSchema": { + "@id": "cred:credentialSchema", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + + "JsonSchemaValidator2018": "cred:JsonSchemaValidator2018" + } + }, + "credentialStatus": {"@id": "cred:credentialStatus", "@type": "@id"}, + "credentialSubject": {"@id": "cred:credentialSubject", "@type": "@id"}, + "evidence": {"@id": "cred:evidence", "@type": "@id"}, + "expirationDate": {"@id": "cred:expirationDate", "@type": "xsd:dateTime"}, + "holder": {"@id": "cred:holder", "@type": "@id"}, + "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, + "issuer": {"@id": "cred:issuer", "@type": "@id"}, + "issuanceDate": {"@id": "cred:issuanceDate", "@type": "xsd:dateTime"}, + "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, + "refreshService": { + "@id": "cred:refreshService", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + + "ManualRefreshService2018": "cred:ManualRefreshService2018" + } + }, + "termsOfUse": {"@id": "cred:termsOfUse", "@type": "@id"}, + "validFrom": {"@id": "cred:validFrom", "@type": "xsd:dateTime"}, + "validUntil": {"@id": "cred:validUntil", "@type": "xsd:dateTime"} + } + }, + + "VerifiablePresentation": { + "@id": "https://www.w3.org/2018/credentials#VerifiablePresentation", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + + "holder": {"@id": "cred:holder", "@type": "@id"}, + "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, + "verifiableCredential": {"@id": "cred:verifiableCredential", "@type": "@id", "@container": "@graph"} + } + }, + + "EcdsaSecp256k1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256k1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "EcdsaSecp256r1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256r1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "Ed25519Signature2018": { + "@id": "https://w3id.org/security#Ed25519Signature2018", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "RsaSignature2018": { + "@id": "https://w3id.org/security#RsaSignature2018", + "@context": { + "@version": 1.1, + "@protected": true, + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "proof": {"@id": "https://w3id.org/security#proof", "@type": "@id", "@container": "@graph"} + } + } + } + + const did = { + documentUrl: iri, + document: { + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + + "alsoKnownAs": { + "@id": "https://www.w3.org/ns/activitystreams#alsoKnownAs", + "@type": "@id" + }, + "assertionMethod": { + "@id": "https://w3id.org/security#assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "https://w3id.org/security#authenticationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityDelegation": { + "@id": "https://w3id.org/security#capabilityDelegationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityInvocation": { + "@id": "https://w3id.org/security#capabilityInvocationMethod", + "@type": "@id", + "@container": "@set" + }, + "controller": { + "@id": "https://w3id.org/security#controller", + "@type": "@id" + }, + "keyAgreement": { + "@id": "https://w3id.org/security#keyAgreementMethod", + "@type": "@id", + "@container": "@set" + }, + "service": { + "@id": "https://www.w3.org/ns/did#service", + "@type": "@id", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "serviceEndpoint": { + "@id": "https://www.w3.org/ns/did#serviceEndpoint", + "@type": "@id" + } + } + }, + "verificationMethod": { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id" + } + } + } + } + + const transmute = { + documentUrl: iri, + document: { + "@context": [ + { + "@version": 1.1 + }, + "https://www.w3.org/ns/did/v1", + { + "JsonWebKey2020": "https://w3id.org/security#JsonWebKey2020", + "Ed25519VerificationKey2018": "https://w3id.org/security#Ed25519VerificationKey2018", + "X25519KeyAgreementKey2019": "https://w3id.org/security#X25519KeyAgreementKey2019", + + "publicKeyJwk": { + "@id": "https://w3id.org/security#publicKeyJwk", + "@type": "@json" + }, + "publicKeyBase58": { + "@id": "https://w3id.org/security#publicKeyBase58" + } + } + ] + } + } + + switch(iri) { + case 'https://www.w3.org/2018/credentials/v1': + return credentials; + case 'https://www.w3.org/ns/did/v1': + return did; + case 'https://ns.did.ai/transmute/v1': + return transmute; + } + } + } + + it('Test VCJS', async function () { + const vcjs = new VCJS(); + assert.exists(vcjs); + + const defaultDocumentLoader = new TestDefaultDocumentLoader(); + const schemaDocumentLoader = new TestContextDocumentLoader('https://ipfs.io/ipfs/'); + const didDocumentLoader = new TestDIDDocumentLoader(); + const vcSchemaObjectLoader = new TestVCSchemaLoader("https://ipfs.io/ipfs/"); + const subjectSchemaObjectLoader = new TestSubjectSchemaLoader("https://ipfs.io/ipfs/"); + + vcjs.addDocumentLoader(defaultDocumentLoader); + vcjs.addDocumentLoader(schemaDocumentLoader); + vcjs.addDocumentLoader(didDocumentLoader); + vcjs.addSchemaLoader(vcSchemaObjectLoader); + vcjs.addSchemaLoader(subjectSchemaObjectLoader); + vcjs.buildDocumentLoader(); + vcjs.buildSchemaLoader(); + + assert.isTrue((await vcjs.verifyVC(actualVcDocument.document))); + assert.isTrue((await vcjs.verifySchema(actualVcDocument.document)).ok); + assert.isTrue((await vcjs.verifySubject(actualVcDocument.document.credentialSubject[0])).ok); + + const createdDidDocument = DIDDocument.create(newPrivateKey); + + const testVc = await vcjs.createVC( + createdDidDocument.getDid(), + createdDidDocument.getPrivateKey(), + vcValueToCreate, + schema + ) + assert.exists(testVc); + assert.isTrue(await vcjs.verifyVC(actualVcDocument.document)); + + const testVp = await vcjs.createVP( + createdDidDocument.getDid(), + createdDidDocument.getPrivateKey(), + [testVc] + ); + assert.exists(testVp); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/hedera-modules/vcjs/vp-document.test.js b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vp-document.test.js new file mode 100644 index 0000000000..0997174a7d --- /dev/null +++ b/guardian-service/tests/unit-tests/hedera-modules/vcjs/vp-document.test.js @@ -0,0 +1,63 @@ +const { expect, assert } = require('chai'); + +const { + VpDocument +} = require('../../../../dist/hedera-modules/vcjs/vp-document'); +const { + VcDocument +} = require('../../../../dist/hedera-modules/vcjs/vc-document'); +const { vp_document } = require('../../dump/vp_document'); + +describe('VpDocument', function () { + + const testId = "testId"; + const testType = "testType"; + const testContext = "testContext"; + const testVpDocument = vp_document[0].document; + const testVpDocumentSecond = vp_document[1].document; + const testVC = testVpDocumentSecond.verifiableCredential[0]; + const testVCs = testVpDocumentSecond.verifiableCredential; + const testVpDocumentThird = vp_document[2].document; + + it('Test VpDocument', async function () { + assert.throws(VpDocument.fromJsonTree); + assert.throws(VpDocument.fromJson); + const vpDocument = VpDocument.fromJsonTree(testVpDocument); + assert.equal(vpDocument.getId(), testVpDocument.id); + assert.deepEqual(vpDocument.getContext(), testVpDocument['@context']); + assert.deepEqual(vpDocument.getType(), testVpDocument.type); + assert.deepEqual(vpDocument.getProof(), testVpDocument.proof); + assert.deepEqual(vpDocument.getVerifiableCredential(0), VcDocument.fromJsonTree(testVpDocument.verifiableCredential[0])); + assert.deepEqual(vpDocument.getVerifiableCredentials(), testVpDocument.verifiableCredential.map(vc => VcDocument.fromJsonTree(vc))); + assert.equal(vpDocument.length, testVpDocument.verifiableCredential.length); + assert.isString(vpDocument.toCredentialHash()); + assert.deepEqual(vpDocument.toJsonTree(), testVpDocument); + assert.deepEqual(vpDocument.getDocument(), testVpDocument); + assert.deepEqual(JSON.parse(vpDocument.toJson()), testVpDocument); + + testVpDocument.id = testId; + vpDocument.setId(testId); + assert.equal(vpDocument.getId(), testVpDocument.id); + + testVpDocument['@context'].push(testContext); + vpDocument.addContext(testContext); + assert.deepEqual(vpDocument.getContext(), testVpDocument['@context']); + + testVpDocument.type.push(testType); + vpDocument.addType(testType); + assert.deepEqual(vpDocument.getType(), testVpDocument.type); + + testVpDocument.proof = vp_document[1].document.proof; + vpDocument.setProof(testVpDocument.proof); + assert.deepEqual(vpDocument.getProof(), testVpDocument.proof); + + testVpDocument.verifiableCredential.push(testVC); + vpDocument.addVerifiableCredential(VcDocument.fromJsonTree(testVC)); + testVpDocument.verifiableCredential.push(...testVCs); + vpDocument.addVerifiableCredentials(testVCs.map((testVC) => VcDocument.fromJsonTree(testVC))); + assert.deepEqual(vpDocument.toJsonTree(), testVpDocument); + + vpDocument.proofFromJson(testVpDocumentThird); + assert.deepEqual(vpDocument.getProof(), testVpDocumentThird.proof); + }); +}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/loader.test.js b/guardian-service/tests/unit-tests/loader.test.js index 2299ae36af..8cd94e78e3 100644 --- a/guardian-service/tests/unit-tests/loader.test.js +++ b/guardian-service/tests/unit-tests/loader.test.js @@ -1,16 +1,16 @@ const { expect, assert } = require('chai'); -const { loaderAPI } = require('./../../dist/api/loader.service'); -const { DIDDocumentLoader } = require('./../../dist/document-loader/did-document-loader'); -const { ContextDocumentLoader } = require('./../../dist/document-loader/context-loader'); -const { VCSchemaLoader } = require('./../../dist/document-loader/vc-schema-loader'); -const { SubjectSchemaLoader } = require('./../../dist/document-loader/subject-schema-loader'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); - -const { - createChannel, - createTable, - checkMessage, - checkError +const { loaderAPI } = require('../../dist/api/loader.service'); +const { DIDDocumentLoader } = require('../../dist/document-loader/did-document-loader'); +const { ContextDocumentLoader } = require('../../dist/document-loader/context-loader'); +const { VCSchemaLoader } = require('../../dist/document-loader/vc-schema-loader'); +const { SubjectSchemaLoader } = require('../../dist/document-loader/subject-schema-loader'); +const { ApplicationState, ApplicationStates } = require('interfaces'); + +const { + createChannel, + createTable, + checkMessage, + checkError } = require('./helper'); describe('Loader service', function () { @@ -111,4 +111,4 @@ describe('Loader service', function () { value = await channel.run(LOAD_SCHEMA_CONTEXT, ["b613e284-5af3-465e-a9a9-329a706180fc"]); checkMessage(value, [schema]); }); -}); \ No newline at end of file +}); diff --git a/guardian-service/tests/unit-tests/schema.test.js b/guardian-service/tests/unit-tests/schema.test.js deleted file mode 100644 index dd971daff6..0000000000 --- a/guardian-service/tests/unit-tests/schema.test.js +++ /dev/null @@ -1,436 +0,0 @@ -require('module-alias/register'); -const { expect, assert } = require('chai'); -const { schemaAPI, schemaCache } = require('./../../dist/api/schema.service'); -const { - createChannel, - createTable, - checkMessage, - checkError -} = require('./helper'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); - -describe('Schema service', function () { - let service, channel; - - const localSchema = 'undefined'; - - const SET_SCHEMA = 'set-schema'; - const GET_SCHEMA = 'get-schema'; - const GET_SCHEMES = 'get-schemes'; - const IMPORT_SCHEMES_BY_MESSAGES = 'IMPORT_SCHEMES_BY_MESSAGES'; - const IMPORT_SCHEMES_BY_FILE = 'IMPORT_SCHEMES_BY_FILE'; - const PREVIEW_SCHEMA = 'preview-schema'; - const PUBLISH_SCHEMA = 'publish-schema'; - const DELETE_SCHEMA = 'delete-schema'; - const EXPORT_SCHEMES = 'export-schema'; - const INCREMENT_SCHEMA_VERSION = 'INCREMENT_SCHEMA_VERSION'; - - const DRAFT = 'DRAFT'; - const PUBLISHED = 'PUBLISHED'; - const UNPUBLISHED = 'UNPUBLISHED'; - - const s1 = { - 'uuid': '0fae2a20-0db2-4835-bab9-99b4effbe03e', - 'iri': '#0fae2a20-0db2-4835-bab9-99b4effbe03e', - 'document': { - '$id': '#0fae2a20-0db2-4835-bab9-99b4effbe03e', - '$comment': '{"term": "0fae2a20-0db2-4835-bab9-99b4effbe03e", "@id": "#0fae2a20-0db2-4835-bab9-99b4effbe03e"}', - 'title': '', - 'description': '', - 'type': 'object', - 'properties': { - '@context': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'type': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'id': { - 'type': 'string' - }, - 'f1': { - 'title': '', - 'description': '', - '$comment': '{"term": "f1", "@id": "https://www.schema.org/text"}', - 'type': 'string' - }, - 'f2': { - 'title': '', - 'description': '', - '$comment': '{"term": "f2", "@id": "https://www.schema.org/text"}', - 'type': 'string' - } - }, - 'required': [ - '@context', - 'type' - ], - 'additionalProperties': false - }, - 'entity': 'entity', - 'name': 'type' - } - - const s2 = { - 'uuid': '59b934e2-9eb6-4395-9b85-ad3624f1f752', - 'document': { - '$id': '#59b934e2-9eb6-4395-9b85-ad3624f1f752', - '$comment': '{"term": "59b934e2-9eb6-4395-9b85-ad3624f1f752", "@id": "#59b934e2-9eb6-4395-9b85-ad3624f1f752"}', - 'title': '', - 'description': '', - 'type': 'object', - 'properties': { - '@context': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'type': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'id': { - 'type': 'string' - }, - 'f3': { - 'title': '', - 'description': '', - 'type': 'array', - 'items': { - '$ref': '#ad2de08d-a43c-43c7-a458-3f0e8db65e8f' - }, - '$comment': '{"term": "f3", "@id": "#ad2de08d-a43c-43c7-a458-3f0e8db65e8f"}' - }, - 'f4': { - 'title': '', - 'description': '', - '$comment': '{"term": "f4", "@id": "https://www.schema.org/text"}', - 'type': 'string' - } - }, - 'required': [ - '@context', - 'type', - 'f3' - ], - 'additionalProperties': false - }, - 'entity': 'entity2', - 'name': 'type2' - } - const s3 = { - 'uuid': 'ad2de08d-a43c-43c7-a458-3f0e8db65e8f', - 'document': { - '$id': '#ad2de08d-a43c-43c7-a458-3f0e8db65e8f', - '$comment': '{"term": "ad2de08d-a43c-43c7-a458-3f0e8db65e8f", "@id": "#ad2de08d-a43c-43c7-a458-3f0e8db65e8f"}', - 'title': '', - 'description': '', - 'type': 'object', - 'properties': { - '@context': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'type': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'id': { - 'type': 'string' - }, - 'f5': { - 'title': '', - 'description': '', - '$comment': '{"term": "f5", "@id": "https://www.schema.org/text"}', - 'type': 'integer' - }, - 'f6': { - 'title': '', - 'description': '', - '$comment': '{"term": "f6", "@id": "https://www.schema.org/text"}', - 'type': 'string', - 'format': 'date' - } - }, - 'required': [ - '@context', - 'type' - ], - 'additionalProperties': false - }, - 'entity': 'entity3', - 'name': 'type3' - } - - const s1db = { - ...s1, - '_id': '1', - 'id': '1', - 'readonly': false, - 'status': PUBLISHED, - } - - let schemas = []; - let index = 0; - - before(async function () { - const state = new ApplicationState(); - state.updateState(ApplicationStates.READY); - - channel = createChannel(); - const schemaRepository = createTable(); - schemaRepository.create = function (items) { - if (Array.isArray(items)) { - for (let i = 0; i < items.length; i++) { - items[i] = Object.assign({ _id: String(++index) }, items[i], true); - items[i].id = items[i]._id - } - return items; - } else { - items = Object.assign({ _id: String(++index) }, items, true); - items.id = items._id - return items; - } - }; - schemaRepository.save = async function (items) { - if (Array.isArray(items)) { - for (let i = 0; i < items.length; i++) { - const element = items[i]; - schemas.push(element); - } - } else { - schemas.push(items); - } - } - schemaRepository.find = async function (param) { - if (!param) { - return schemas; - } - return param; - } - - schemaRepository.findOne = async function (param) { - if (param === 0) { - return schemas[0]; - } - if (param === 1) { - return null; - } - if (!param) { - return schemas; - } - return param; - } - - schemaRepository.update = async function (id, item) { - const i = schemas.findIndex(e => e._id == id); - if (i > -1) { - schemas[i] = item - } - } - - schemaRepository.delete = async function (id) { - schemas = schemas.filter(e => e._id != id); - } - - service = schemaAPI( - channel, - schemaRepository - ); - - schemaCache['0fae2a20-0db2-4835-bab9-99b4effbe03e'] = s1; - }); - - it('Config service init', async function () { - assert.exists(channel.map[SET_SCHEMA]); - assert.exists(channel.map[GET_SCHEMA]); - assert.exists(channel.map[GET_SCHEMES]); - assert.exists(channel.map[IMPORT_SCHEMES_BY_MESSAGES]); - assert.exists(channel.map[IMPORT_SCHEMES_BY_FILE]); - assert.exists(channel.map[PREVIEW_SCHEMA]); - assert.exists(channel.map[PUBLISH_SCHEMA]); - assert.exists(channel.map[DELETE_SCHEMA]); - assert.exists(channel.map[EXPORT_SCHEMES]); - assert.exists(channel.map[INCREMENT_SCHEMA_VERSION]); - }); - - it('Test SET_SCHEMA', async function () { - let value = await channel.run(SET_SCHEMA, { - uuid: '0fae2a20-0db2-4835-bab9-99b4effbe03e', - name: 'type', - entity: 'entity', - readonly: false, - status: PUBLISHED, - document: { - '$id': '#0fae2a20-0db2-4835-bab9-99b4effbe03e', - '$comment': '{"term": "0fae2a20-0db2-4835-bab9-99b4effbe03e", "@id": "#0fae2a20-0db2-4835-bab9-99b4effbe03e"}', - 'title': '', - 'description': '', - 'type': 'object', - 'properties': { - '@context': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'type': { - 'oneOf': [ - { - 'type': 'string' - }, - { - 'type': 'array', - 'items': { - 'type': 'string' - } - } - ] - }, - 'id': { - 'type': 'string' - }, - 'f1': { - 'title': '', - 'description': '', - '$comment': '{"term": "f1", "@id": "https://www.schema.org/text"}', - 'type': 'string' - }, - 'f2': { - 'title': '', - 'description': '', - '$comment': '{"term": "f2", "@id": "https://www.schema.org/text"}', - 'type': 'string' - } - }, - 'required': [ - '@context', - 'type' - ], - 'additionalProperties': false - } - }); - checkMessage(value, [{ ...s1db, status: DRAFT, iri: '#0fae2a20-0db2-4835-bab9-99b4effbe03e', version: null }]); - }); - - it('Test GET_SCHEMA', async function () { - let value = await channel.run(GET_SCHEMA, null); - checkError(value, 'Invalid load schema parameter'); - - value = await channel.run(GET_SCHEMA, { id: "id" }); - checkMessage(value, "id"); - }); - - it('Test GET_SCHEMES', async function () { - let value = await channel.run(GET_SCHEMES, null); - checkError(value, 'Invalid load schema parameter'); - - value = await channel.run(GET_SCHEMES, { uuid: 'uuid' }); - checkMessage(value, { - uuid: 'uuid' - }); - - value = await channel.run(GET_SCHEMES, { owner: 'owner1' }); - checkMessage(value, { - where: { - "$or": [ - { - status: "PUBLISHED" - - }, { - owner: "owner1" - - } - ] - } - }); - }); - - it('Test IMPORT_SCHEMES_BY_MESSAGES', async function () { - let value = await channel.run(IMPORT_SCHEMES_BY_MESSAGES, null); - checkError(value, 'Invalid import schema parameter'); - - value = await channel.run(IMPORT_SCHEMES_BY_MESSAGES, { messageIds: "messageIds" }); - checkError(value, 'Invalid import schema parameter'); - - value = await channel.run(IMPORT_SCHEMES_BY_MESSAGES, { owner: "owner" }); - checkError(value, 'Invalid import schema parameter'); - }); - - it('Test PREVIEW_SCHEMA', async function () { - let value = await channel.run(PREVIEW_SCHEMA, null); - checkError(value, 'Invalid preview schema parameters'); - }); - - it('Test PUBLISH_SCHEMA', async function () { - let value = await channel.run(PUBLISH_SCHEMA, null); - checkError(value, 'Invalid id'); - }); - - it('Test DELETE_SCHEMA', async function () { - let value = await channel.run(DELETE_SCHEMA, '2'); - checkMessage(value, schemas); - }); -}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/token.test.js b/guardian-service/tests/unit-tests/token.test.js deleted file mode 100644 index 0804133871..0000000000 --- a/guardian-service/tests/unit-tests/token.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const { expect, assert } = require('chai'); -const { tokenAPI } = require('./../../dist/api/token.service'); -const { - createChannel, - createTable, - checkMessage, - checkError -} = require('./helper'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); - -describe('Token service', function () { - let service, channel; - - const SET_TOKEN = 'set-token'; - const GET_TOKENS = 'get-tokens'; - - const tokens = []; - - before(async function () { - const state = new ApplicationState(); - state.updateState(ApplicationStates.READY); - - channel = createChannel(); - const tokenRepository = createTable(); - tokenRepository.create = function (items) { - return items = Object.assign({ _id: '1' }, items, true); - }; - tokenRepository.save = async function (items) { - tokens.push(items); - } - tokenRepository.find = async function (param) { - if (!param) { - return tokens; - } - return param; - } - service = tokenAPI(channel, - tokenRepository, - ); - }); - - it('Config service init', async function () { - assert.exists(channel.map[SET_TOKEN]); - assert.exists(channel.map[GET_TOKENS]); - }); - - it('Test SET_TOKEN', async function () { - tokens.push({ - _id: '1', - tokenId: 'tokenId', - tokenName: 'tokenName', - tokenSymbol: 'tokenSymbol', - tokenType: 'tokenType', - decimals: 'decimals', - initialSupply: 'initialSupply', - adminId: 'adminId', - adminKey: 'adminKey', - kycKey: 'kycKey', - freezeKey: 'freezeKey', - wipeKey: 'wipeKey', - supplyKey: 'supplyKey' - }); - }); - - it('Test GET_TOKENS', async function () { - let value = await channel.run(GET_TOKENS, null); - checkMessage(value, [{ - _id: '1', - tokenId: 'tokenId', - tokenName: 'tokenName', - tokenSymbol: 'tokenSymbol', - tokenType: 'tokenType', - decimals: 'decimals', - initialSupply: 'initialSupply', - adminId: 'adminId', - adminKey: 'adminKey', - kycKey: 'kycKey', - freezeKey: 'freezeKey', - wipeKey: 'wipeKey', - supplyKey: 'supplyKey' - }]); - - value = await channel.run(GET_TOKENS, { tokenId: 'tokenId' }); - checkMessage(value, { where: { tokenId: { '$eq': 'tokenId' } } }); - }); -}); \ No newline at end of file diff --git a/guardian-service/tests/unit-tests/trust-chain.test.js b/guardian-service/tests/unit-tests/trust-chain.test.js index 0cf4cbc733..1be17eccca 100644 --- a/guardian-service/tests/unit-tests/trust-chain.test.js +++ b/guardian-service/tests/unit-tests/trust-chain.test.js @@ -1,5 +1,5 @@ const { expect, assert } = require('chai'); -const { trustChainAPI } = require('./../../dist/api/trust-chain.service'); +const { trustChainAPI } = require('../../dist/api/trust-chain.service'); const { did_document } = require('./dump/did_document'); const { vc_document } = require('./dump/vc_document'); const { vp_document } = require('./dump/vp_document'); @@ -10,7 +10,7 @@ const { checkMessage, checkError } = require('./helper'); -const { ApplicationState, ApplicationStates } = require('./../../dist/helpers/application-state'); +const { ApplicationState, ApplicationStates } = require('interfaces'); describe('Trust Chain service', function () { let service, channel; @@ -123,4 +123,4 @@ describe('Trust Chain service', function () { value = await channel.run(GET_CHAIN, '5LDizXoaXcqYmdbGUfsRrzf5PpgWmiUuarmTNgTxAYyU'); checkMessage(value, testObject2); }); -}); \ No newline at end of file +}); diff --git a/guardian-service/tsconfig.json b/guardian-service/tsconfig.json index b9cb869cea..92721fd2f6 100644 --- a/guardian-service/tsconfig.json +++ b/guardian-service/tsconfig.json @@ -12,6 +12,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "esModuleInterop": true, + "skipLibCheck": true, "baseUrl": "./src", "paths": { "@entity/*": ["entity/*"], diff --git a/interfaces/package-lock.json b/interfaces/package-lock.json index 4f3cabd3a8..c9f11e8b85 100644 --- a/interfaces/package-lock.json +++ b/interfaces/package-lock.json @@ -1,12 +1,12 @@ { "name": "interfaces", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "interfaces", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" diff --git a/interfaces/package.json b/interfaces/package.json index ab1357bc1d..91ff2ac587 100644 --- a/interfaces/package.json +++ b/interfaces/package.json @@ -23,5 +23,5 @@ "lint": "tslint --project .", "test": "echo \"Error: no test specified\" && exit 1" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/interfaces/src/helpers/schema-helper.ts b/interfaces/src/helpers/schema-helper.ts index ab13f747c7..3605627bb3 100644 --- a/interfaces/src/helpers/schema-helper.ts +++ b/interfaces/src/helpers/schema-helper.ts @@ -1,9 +1,7 @@ -import { ModelHelper } from './model-helper'; -import { ISchemaDocument, SchemaDataTypes } from '../interface/schema-document.interface'; -import { ISchema } from '../interface/schema.interface'; +import { ISchema, ISchemaDocument, SchemaCondition, SchemaField } from '..'; +import { SchemaDataTypes } from '../interface/schema-document.interface'; import { Schema } from '../models/schema'; -import { SchemaField } from "../interface/schema-field.interface"; -import { SchemaCondition } from '..'; +import { ModelHelper } from './model-helper'; export class SchemaHelper { public static parseRef(data: string | ISchema): { @@ -530,7 +528,7 @@ export class SchemaHelper { public static updateIRI(schema: ISchema): ISchema { try { if (schema.document) { - let document = schema.document; + let document = schema.document; if (typeof document == "string") { document = JSON.parse(document) as ISchemaDocument; } diff --git a/interfaces/src/index.ts b/interfaces/src/index.ts index 7f5c4211ab..44a26fbcd5 100644 --- a/interfaces/src/index.ts +++ b/interfaces/src/index.ts @@ -35,11 +35,9 @@ export { SchemaCondition } from './interface/schema-condition.interface'; export { ModelHelper } from './helpers/model-helper'; export { ImportType } from './type/import.type'; export { SchemaHelper } from './helpers/schema-helper'; -export { IMessageResponse, MessageResponse, MessageError, MessageInitialization, Response } from './models/message-response'; export { WalletEvents } from './type/wallet-events'; export { SchemaCategory } from './type/schema-category.type'; export { CommonSettings } from './interface/common-settings.interface'; -export { Singleton } from './decorators/singleton'; export { ILog } from './interface/log.interface'; export { LogType } from './type/log.type'; export { IPageParameters } from './interface/page-parameters.interface'; @@ -49,4 +47,4 @@ export { UserType } from './type/user.type'; export { IDidDocument } from './interface/did-document'; export { IVerificationMethod } from './interface/verification-method'; export { ApplicationStates } from './type/application-states.type'; -export { ApplicationState } from './helpers/application-state'; +export * from './interface/messages'; \ No newline at end of file diff --git a/interfaces/src/interface/messages/account.message.ts b/interfaces/src/interface/messages/account.message.ts new file mode 100644 index 0000000000..9d44e901bc --- /dev/null +++ b/interfaces/src/interface/messages/account.message.ts @@ -0,0 +1,59 @@ +import { UserRole } from "../../type/user-role.type"; +import { IUser } from "../user.interface"; + +export interface IGetUserMessage { + username: string; +} +export interface IGetUserByTokenMessage { + token: string; +} +export interface IRegisterNewUserMessage { + username: string; + password: string; + role: UserRole; +} +export interface IGenerateTokenMessage { + username: string; + password: string; +} +export interface IGenerateTokenResponse { + username: string; + accessToken: string; + role: UserRole; + did: string; +} +export interface IGetAllUserResponse { + username: string; + parent: string; + did: string; +} + +export interface IRootAuthorityUserResponse { + username: string; + did: string; +} + +export interface IGetDemoUserResponse extends IGetAllUserResponse { + role: UserRole; +} + +export interface IUpdateUserMessage { + username: string; + item: Partial; +} + +export interface ISaveUserMessage { + user: IUser; +} + +export interface IGetUserByIdMessage { + did: string; +} + +export interface IGetUsersByIdMessage { + dids: string[]; +} + +export interface IGetUsersByIRoleMessage { + role: UserRole; +} \ No newline at end of file diff --git a/interfaces/src/interface/messages/auth.message.ts b/interfaces/src/interface/messages/auth.message.ts new file mode 100644 index 0000000000..7591a72b25 --- /dev/null +++ b/interfaces/src/interface/messages/auth.message.ts @@ -0,0 +1,12 @@ +export interface IGetKeyMessage { + token: string; + type: string; + key: string +} +export interface ISetKeyMessage extends IGetKeyMessage { + value: string; +} + +export interface IGetKeyResponse { + key: string; +} \ No newline at end of file diff --git a/interfaces/src/interface/messages/index.ts b/interfaces/src/interface/messages/index.ts new file mode 100644 index 0000000000..5070cd5799 --- /dev/null +++ b/interfaces/src/interface/messages/index.ts @@ -0,0 +1,5 @@ +export * from './socket.message'; +export * from './ipfs.message'; +export * from './log.message'; +export * from './auth.message'; +export * from './account.message'; \ No newline at end of file diff --git a/interfaces/src/interface/messages/ipfs.message.ts b/interfaces/src/interface/messages/ipfs.message.ts new file mode 100644 index 0000000000..3bf282d104 --- /dev/null +++ b/interfaces/src/interface/messages/ipfs.message.ts @@ -0,0 +1,17 @@ +export interface IFileResponse { + cid: string; + url: string; +} + +export interface IGetFileMessage { + cid: string; + responseType: 'raw' | 'str' | 'json' +} + +export interface IAddFileMessage { + content: string; +} + +export interface IIpfsSettingsResponse { + nftApiKey: string; +} \ No newline at end of file diff --git a/interfaces/src/interface/messages/log.message.ts b/interfaces/src/interface/messages/log.message.ts new file mode 100644 index 0000000000..61ca7019f1 --- /dev/null +++ b/interfaces/src/interface/messages/log.message.ts @@ -0,0 +1,18 @@ +import { ILog } from "../log.interface"; +import { IPageParameters } from "../page-parameters.interface" + +export interface IGetLogsMessage { + filters?: { [x: string]: any } + pageParameters?: IPageParameters; + sortDirection?: 'ASC' | 'DESC'; +} + +export interface IGetLogsResponse { + logs: ILog[]; + totalCount: number; +} + +export interface IGetLogAttributesMessage { + name: string; + existingAttributes: string[]; +} \ No newline at end of file diff --git a/interfaces/src/interface/messages/socket.message.ts b/interfaces/src/interface/messages/socket.message.ts new file mode 100644 index 0000000000..b2f8f1b426 --- /dev/null +++ b/interfaces/src/interface/messages/socket.message.ts @@ -0,0 +1,12 @@ +export interface IUpdateBlockMessage { + uuid: string +} + +export interface IErrorBlockMessage { + uuid: string; + user: { + did: string + }; + blockType: string; + message: any; +} diff --git a/interfaces/src/models/schema.ts b/interfaces/src/models/schema.ts index f83db4571e..396483c7f7 100644 --- a/interfaces/src/models/schema.ts +++ b/interfaces/src/models/schema.ts @@ -1,11 +1,11 @@ import { ModelHelper } from '../helpers/model-helper'; +import { SchemaHelper } from '../helpers/schema-helper'; +import { SchemaCondition } from '../interface/schema-condition.interface'; import { ISchemaDocument } from '../interface/schema-document.interface'; +import { SchemaField } from '../interface/schema-field.interface'; import { ISchema } from '../interface/schema.interface'; import { SchemaEntity } from '../type/schema-entity.type'; import { SchemaStatus } from '../type/schema-status.type'; -import { SchemaHelper } from '../helpers/schema-helper'; -import { SchemaField } from '../interface/schema-field.interface'; -import { SchemaCondition } from '../interface/schema-condition.interface'; export class Schema implements ISchema { public id: string; @@ -58,7 +58,7 @@ export class Schema implements ISchema { if (schema.isCreator) { this.userDID = this.creator; } - if(schema.document) { + if (schema.document) { if (typeof schema.document == 'string') { this.document = JSON.parse(schema.document); } else { @@ -67,7 +67,7 @@ export class Schema implements ISchema { } else { this.document = null; } - if(schema.context) { + if (schema.context) { if (typeof schema.context == 'string') { this.context = JSON.parse(schema.context); } else { diff --git a/interfaces/src/models/token.ts b/interfaces/src/models/token.ts index 9a68f278fa..6cb366cc55 100644 --- a/interfaces/src/models/token.ts +++ b/interfaces/src/models/token.ts @@ -1,4 +1,4 @@ -import {IToken, ITokenInfo} from '../interface/token.interface'; +import { IToken, ITokenInfo } from ".."; export class Token { public tokenId: string; diff --git a/interfaces/tsconfig.json b/interfaces/tsconfig.json index c7c58b14fb..a10534fb71 100644 --- a/interfaces/tsconfig.json +++ b/interfaces/tsconfig.json @@ -3,6 +3,7 @@ "module": "commonjs", "target": "es6", "lib": [ + "dom", "es5", "es6" ], diff --git a/ipfs-client/.env.docker b/ipfs-client/.env.docker index 1aa3e02bc0..31a74deed4 100644 --- a/ipfs-client/.env.docker +++ b/ipfs-client/.env.docker @@ -2,4 +2,4 @@ MQ_ADDRESS="message-broker" SERVICE_CHANNEL="ipfs-client" DB_HOST="mongo" DB_DATABASE="ipfs_client_db" -NFT_API_KEY="..." \ No newline at end of file +NFT_API_KEY="..." diff --git a/ipfs-client/Dockerfile b/ipfs-client/Dockerfile index 6c7a0a2101..54e0de6e9e 100644 --- a/ipfs-client/Dockerfile +++ b/ipfs-client/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/logger-helper COPY ./logger-helper/package*.json ./ COPY ./logger-helper/tsconfig.json ./ diff --git a/ipfs-client/nodemon.json b/ipfs-client/nodemon.json new file mode 100644 index 0000000000..660aa69975 --- /dev/null +++ b/ipfs-client/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/ipfs-client/package-lock.json b/ipfs-client/package-lock.json index 27557bb835..46f8bba516 100644 --- a/ipfs-client/package-lock.json +++ b/ipfs-client/package-lock.json @@ -1,21 +1,21 @@ { "name": "ipfs-client", - "version": "1.0.5", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ipfs-client", - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "@web-std/fetch": "3.0.0", "axios": "^0.26.1", "axios-retry": "^3.2.4", + "common": "file:../common", "cors": "^2.8.5", "cross-blob": "^2.0.1", "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", "js-yaml": "^4.1.0", @@ -39,9 +39,27 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", + "dependencies": { + "reflect-metadata": "^0.1.13" + }, "devDependencies": { "@types/node": "^17.0.13", "mocha-junit-reporter": "^2.0.2", @@ -50,10 +68,10 @@ } }, "../logger-helper": { - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces" }, "devDependencies": { @@ -641,11 +659,6 @@ "multiformats": "^9.4.7" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -781,14 +794,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -1062,6 +1067,10 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/complex.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.0.tgz", @@ -1297,11 +1306,6 @@ "node": ">=12" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -1458,37 +1462,11 @@ "node": ">=6" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "node_modules/fast-fifo": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==" }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/fetch-blob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", @@ -1705,11 +1683,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1981,11 +1954,6 @@ "node": ">=10" } }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interface-blockstore": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-2.0.3.tgz", @@ -2804,11 +2772,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -3268,11 +3231,6 @@ "node": "4.x || >=6.0.0" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -5693,11 +5651,6 @@ "multiformats": "^9.4.7" } }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -5785,14 +5738,6 @@ "ieee754": "^1.2.1" } }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -5995,6 +5940,18 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "complex.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.0.tgz", @@ -6168,11 +6125,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -6292,34 +6244,11 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "fast-fifo": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==" }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, "fetch-blob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", @@ -6468,11 +6397,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -6652,11 +6576,6 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interface-blockstore": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-2.0.3.tgz", @@ -6686,6 +6605,7 @@ "requires": { "@types/node": "^17.0.13", "mocha-junit-reporter": "^2.0.2", + "reflect-metadata": "^0.1.13", "tslint": "^6.1.3", "typescript": "^4.5.5" } @@ -7311,11 +7231,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -7330,7 +7245,7 @@ "version": "file:../logger-helper", "requires": { "@types/node": "^17.0.13", - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces", "mocha-junit-reporter": "^2.0.2", "tslint": "^6.1.3", @@ -7683,11 +7598,6 @@ "version": "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g==" }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", diff --git a/ipfs-client/package.json b/ipfs-client/package.json index ed7ad37e85..ae6bf4b80d 100644 --- a/ipfs-client/package.json +++ b/ipfs-client/package.json @@ -10,7 +10,6 @@ "cors": "^2.8.5", "cross-blob": "^2.0.1", "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", "js-yaml": "^4.1.0", @@ -20,6 +19,7 @@ "mongodb": "^4.2.1", "reflect-metadata": "^0.1.13", "typeorm": "^0.2.41", + "common":"file:../common", "logger-helper": "file:../logger-helper" }, "description": "", @@ -41,10 +41,11 @@ "watch": "nodemon src/index.ts", "build": "tsc", "debug": "nodemon dist/index.js", + "dev:docker": "npm run build && nodemon .", "dev": "tsc -w", "lint": "tslint --project .", "start": "node dist/index.js", "test": "mocha tests/**/*.test.js --reporter mocha-junit-reporter --reporter-options mochaFile=../test_results/ipfs-client.xml" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/ipfs-client/src/api/file.service.ts b/ipfs-client/src/api/file.service.ts index 49e12a7777..cb1af0eeb4 100644 --- a/ipfs-client/src/api/file.service.ts +++ b/ipfs-client/src/api/file.service.ts @@ -1,11 +1,19 @@ -import { CommonSettings, MessageAPI } from 'interfaces'; import { NFTStorage } from 'nft.storage'; import Blob from 'cross-blob'; -import axios, { ResponseType } from 'axios'; +import axios from 'axios'; import axiosRetry from 'axios-retry'; import { MongoRepository } from 'typeorm'; import { Settings } from '../entity/settings'; import { Logger } from 'logger-helper'; +import { + MessageAPI, + CommonSettings, + IGetFileMessage, + IIpfsSettingsResponse, + IAddFileMessage, + IFileResponse +} from 'interfaces'; +import { MessageBrokerChannel, MessageError, MessageResponse } from 'common'; export const IPFS_PUBLIC_GATEWAY = 'https://ipfs.io/ipfs'; @@ -17,7 +25,7 @@ export const IPFS_PUBLIC_GATEWAY = 'https://ipfs.io/ipfs'; * @param node - IPFS client */ export const fileAPI = async function ( - channel: any, + channel: MessageBrokerChannel, client: NFTStorage, settingsRepository: MongoRepository ): Promise { @@ -28,24 +36,17 @@ export const fileAPI = async function ( * * @returns {string} - hash of added file */ - channel.response(MessageAPI.IPFS_ADD_FILE, async (msg, res) => { + channel.response(MessageAPI.IPFS_ADD_FILE, async (msg) => { try { - let blob = new Blob([msg.payload]); + let blob = new Blob([Buffer.from(msg.content, 'base64')]); const cid = await client.storeBlob(blob); const url = `${IPFS_PUBLIC_GATEWAY}/${cid}`; - const response = { - body: { cid, url }, - error: null - } - res.send(response, 'json'); + + return new MessageResponse({ cid, url },); } catch (e) { new Logger().error(e.toString(), ['IPFS_CLIENT']); - const response = { - body: null, - error: e.message - } - res.send(response, 'json'); + return new MessageError(e.message); } }) @@ -57,53 +58,51 @@ export const fileAPI = async function ( * * @return {any} - File */ - channel.response(MessageAPI.IPFS_GET_FILE, async (msg, res) => { + channel.response(MessageAPI.IPFS_GET_FILE, async (msg) => { try { - axiosRetry(axios, { retries: 3, + axiosRetry(axios, { + retries: 3, shouldResetTimeout: true, retryCondition: (error) => axiosRetry.isNetworkOrIdempotentRequestError(error) || error.code === 'ECONNABORTED', retryDelay: (retryCount) => 10000 }); - if (!msg.payload || !msg.payload.cid || !msg.payload.responseType) { + if (!msg || !msg.cid || !msg.responseType) { throw 'Invalid cid'; } - const fileRes = await axios.get(`${IPFS_PUBLIC_GATEWAY}/${msg.payload.cid}`, { responseType: 'arraybuffer', timeout: 20000 }); - switch (msg.payload.responseType) { + const fileRes = await axios.get(`${IPFS_PUBLIC_GATEWAY}/${msg.cid}`, { responseType: 'arraybuffer', timeout: 20000 }); + switch (msg.responseType) { case 'str': - res.send({ body: Buffer.from(fileRes.data, 'binary').toString() }); - return; + return new MessageResponse(Buffer.from(fileRes.data, 'binary').toString()); case 'json': - res.send({ body: Buffer.from(fileRes.data, 'binary').toJSON() }); - return; + return new MessageResponse(Buffer.from(fileRes.data, 'binary').toJSON()); default: - res.send({ body: fileRes.data }) - return; + return new MessageResponse(fileRes.data) } } catch (e) { new Logger().error(e.toString(), ['IPFS_CLIENT']); - res.send({ error: e.message }); + return new MessageResponse({ error: e.message }); } }) /** * Update settings. * - * @param {CommonSettings} [payload] - Settings + * @param {CommonSettings} [msg] - Settings * */ - channel.response(MessageAPI.UPDATE_SETTINGS, async (msg, res) => { + channel.response(MessageAPI.UPDATE_SETTINGS, async (settings) => { try { - const settings = msg.payload as CommonSettings; const oldNftApiKey = await settingsRepository.findOne({ name: 'NFT_API_KEY' }); if (oldNftApiKey) { await settingsRepository.update({ - name: 'NFT_API_KEY' }, { + name: 'NFT_API_KEY' + }, { value: settings.nftApiKey }); } @@ -115,11 +114,11 @@ export const fileAPI = async function ( } client = new NFTStorage({ token: settings.nftApiKey }); - res.send({}); + return new MessageResponse({}); } catch (e) { new Logger().error(e.toString(), ['IPFS_CLIENT']); - res.send({ error: e.message }); + return new MessageResponse({ error: e.message }); } }) @@ -128,12 +127,12 @@ export const fileAPI = async function ( * * @return {any} - settings */ - channel.response(MessageAPI.GET_SETTINGS, async (msg, res) => { + channel.response(MessageAPI.GET_SETTINGS, async (_) => { const nftApiKey = await settingsRepository.findOne({ name: "NFT_API_KEY" }); - res.send({body: { + return new MessageResponse({ nftApiKey: nftApiKey?.value || process.env.NFT_API_KEY - }}); + }); }) } diff --git a/ipfs-client/src/app.ts b/ipfs-client/src/app.ts index b2f7ac9441..4845765646 100644 --- a/ipfs-client/src/app.ts +++ b/ipfs-client/src/app.ts @@ -1,8 +1,8 @@ -import FastMQ from 'fastmq'; -import { ApplicationState, ApplicationStates } from 'interfaces'; +import { ApplicationStates } from 'interfaces'; import { Logger } from 'logger-helper'; import { NFTStorage } from 'nft.storage'; import { createConnection } from 'typeorm'; +import { MessageBrokerChannel, ApplicationState } from 'common'; import { fileAPI } from './api/file.service'; import { Settings } from './entity/settings'; @@ -23,10 +23,12 @@ Promise.all([ entitiesDir: 'dist/entity' } }), - FastMQ.Client.connect(process.env.SERVICE_CHANNEL, 7500, process.env.MQ_ADDRESS), + MessageBrokerChannel.connect("IPFS_CLIENT") ]).then(async values => { - const [db, channel] = values; + const [db, cn] = values; const state = new ApplicationState('IPFS_CLIENT'); + const channel = new MessageBrokerChannel(cn, 'ipfs-client'); + state.setChannel(channel); state.updateState(ApplicationStates.STARTED); const settingsRepository = db.getMongoRepository(Settings); diff --git a/ipfs-client/src/config.ts b/ipfs-client/src/config.ts index 401e98a3c9..6a6add81f1 100644 --- a/ipfs-client/src/config.ts +++ b/ipfs-client/src/config.ts @@ -2,6 +2,6 @@ import dotenv from 'dotenv'; dotenv.config(); -if(!process.env.NFT_API_KEY || process.env.NFT_API_KEY.length<20) { +if (!process.env.NFT_API_KEY || process.env.NFT_API_KEY.length < 20) { throw ('You need to fill NFT_API_KEY field in .env file'); } \ No newline at end of file diff --git a/ipfs-client/tsconfig.json b/ipfs-client/tsconfig.json index e63cf1461c..debbf26a24 100644 --- a/ipfs-client/tsconfig.json +++ b/ipfs-client/tsconfig.json @@ -10,7 +10,8 @@ "moduleResolution": "node", "sourceMap": true, "outDir": "dist/", - "esModuleInterop": true + "esModuleInterop": true, + "skipLibCheck": true, }, "include": [ "src/**/*" diff --git a/logger-helper/package-lock.json b/logger-helper/package-lock.json index ff4d586916..f816321d5c 100644 --- a/logger-helper/package-lock.json +++ b/logger-helper/package-lock.json @@ -1,15 +1,15 @@ { "name": "logger-helper", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "logger-helper", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "fastmq": "^1.3.8", + "common": "file:../common", "interfaces": "file:../interfaces" }, "devDependencies": { @@ -19,8 +19,23 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" @@ -138,17 +153,6 @@ "node": ">=4" } }, - "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", @@ -234,11 +238,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -269,14 +268,6 @@ "dev": true, "peer": true }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -286,18 +277,6 @@ "node": ">=0.10.0" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -416,6 +395,10 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -479,11 +462,6 @@ "node": ">=0.3.1" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -527,46 +505,6 @@ "node": ">=4" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/fastmq/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -631,7 +569,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", @@ -643,19 +582,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -689,11 +615,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -708,6 +629,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -725,31 +647,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -776,11 +673,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interfaces": { "resolved": "../interfaces", "link": true @@ -869,21 +761,6 @@ "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "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-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -939,11 +816,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -961,17 +833,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -998,7 +859,8 @@ "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", @@ -1107,11 +969,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1224,11 +1081,6 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1610,11 +1462,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -1759,14 +1606,6 @@ } } }, - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", @@ -1834,11 +1673,6 @@ "dev": true, "peer": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1866,29 +1700,12 @@ "dev": true, "peer": true }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -1977,6 +1794,18 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2022,11 +1851,6 @@ "dev": true, "peer": true }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2054,39 +1878,6 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2132,7 +1923,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -2141,16 +1933,6 @@ "dev": true, "peer": true }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -2175,11 +1957,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -2191,6 +1968,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -2202,19 +1980,6 @@ "dev": true, "peer": true }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2238,11 +2003,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interfaces": { "version": "file:../interfaces", "requires": { @@ -2316,15 +2076,6 @@ "dev": true, "peer": true }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -2365,11 +2116,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -2381,14 +2127,6 @@ "is-unicode-supported": "^0.1.0" } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", @@ -2412,7 +2150,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -2500,11 +2239,6 @@ "dev": true, "peer": true }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2587,11 +2321,6 @@ "picomatch": "^2.2.1" } }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2866,11 +2595,6 @@ "dev": true, "peer": true }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/logger-helper/package.json b/logger-helper/package.json index 3a650ee677..19f75fa800 100644 --- a/logger-helper/package.json +++ b/logger-helper/package.json @@ -2,8 +2,8 @@ "author": "Envision Blockchain Solutions ", "description": "", "dependencies": { - "fastmq": "^1.3.8", - "interfaces": "file:../interfaces" + "interfaces": "file:../interfaces", + "common": "file:../common" }, "devDependencies": { "@types/node": "^17.0.13", @@ -24,5 +24,5 @@ "lint": "tslint --project .", "test": "echo \"Error: no test specified\" && exit 1" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/logger-helper/src/helpers/logger.ts b/logger-helper/src/helpers/logger.ts index dc54ac2c9c..66bab9508f 100644 --- a/logger-helper/src/helpers/logger.ts +++ b/logger-helper/src/helpers/logger.ts @@ -1,23 +1,23 @@ -import { ApplicationStates, ILog, IPageParameters, LogType, MessageAPI, Singleton } from 'interfaces'; -import { IMessageResponse } from 'interfaces'; +import { ApplicationStates, ILog, IPageParameters, LogType, MessageAPI } from 'interfaces'; +import { MessageBrokerChannel, Singleton, IMessageResponse } from 'common'; @Singleton export class Logger { - private channel: any; + private channel: MessageBrokerChannel; private readonly target: string = "logger-service"; /** * Register channel * @param channel */ - public setChannel(channel: any): any { + public setChannel(channel: MessageBrokerChannel): any { this.channel = channel; } /** * Get channel */ - public getChannel(): any { + public getChannel(): MessageBrokerChannel { return this.channel; } @@ -25,11 +25,10 @@ export class Logger { * Request to logger service method * @param entity * @param params - * @param type */ - public async request(entity: string, params?: any, type?: string): Promise { + public async request(entity: string, params?: any): Promise { try { - const response: IMessageResponse = (await this.channel.request(this.target, entity, params, type)).payload; + const response: IMessageResponse = await this.channel.request([this.target, entity].join('.'), params); if (!response) { throw Error('Server is not available'); } @@ -42,14 +41,12 @@ export class Logger { } } - - private async write(type: LogType, message: string, attr?: string[]) { const logMessage: ILog = { message: message, type: type, attributes: attr - } + } await this.request(MessageAPI.WRITE_LOG, logMessage); } @@ -72,7 +69,7 @@ export class Logger { } public async getAttributes(name?: string, existingAttributes: string[] = []): Promise { - return await this.request(MessageAPI.GET_ATTRIBUTES, { name, existingAttributes}); + return await this.request(MessageAPI.GET_ATTRIBUTES, { name, existingAttributes }); } /** diff --git a/logger-helper/tsconfig.json b/logger-helper/tsconfig.json index c7c58b14fb..f6bda6ab76 100644 --- a/logger-helper/tsconfig.json +++ b/logger-helper/tsconfig.json @@ -12,7 +12,8 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "esModuleInterop": true, - "declaration": true + "declaration": true, + "skipLibCheck": true, }, "include": [ "src/**/*" diff --git a/logger-service/Dockerfile b/logger-service/Dockerfile index 13d03eba7c..177624f4a8 100644 --- a/logger-service/Dockerfile +++ b/logger-service/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/logger-service COPY ./logger-service/package*.json ./ COPY ./logger-service/tsconfig.json ./ diff --git a/logger-service/nodemon.json b/logger-service/nodemon.json new file mode 100644 index 0000000000..8b879fd87b --- /dev/null +++ b/logger-service/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist", "../logger-helper/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/logger-service/package-lock.json b/logger-service/package-lock.json index bdfcf85313..8a74d173b8 100644 --- a/logger-service/package-lock.json +++ b/logger-service/package-lock.json @@ -1,18 +1,18 @@ { "name": "logger-service", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "logger-service", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "@web-std/fetch": "3.0.0", + "common": "file:../common", "cors": "^2.8.5", "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", "module-alias": "^2.2.2", @@ -31,8 +31,23 @@ "typescript": "^4.5.5" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../interfaces": { - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "reflect-metadata": "^0.1.13" @@ -150,17 +165,6 @@ "node": ">=4" } }, - "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -406,11 +410,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -517,14 +516,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -768,6 +759,10 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -948,11 +943,6 @@ "node": ">=12" } }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -1064,32 +1054,6 @@ "node": ">=4" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1257,11 +1221,6 @@ "node": ">= 6" } }, - "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==" - }, "node_modules/global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -1463,11 +1422,6 @@ "node": ">=10" } }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "node_modules/interfaces": { "resolved": "../interfaces", "link": true @@ -1910,11 +1864,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -1953,6 +1902,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -2024,7 +1974,8 @@ "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", @@ -2183,11 +2134,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "node_modules/nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -2564,11 +2510,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "node_modules/registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -2667,6 +2608,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -3565,7 +3507,8 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/yargs": { "version": "16.2.0", @@ -3719,14 +3662,6 @@ } } }, - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -3919,11 +3854,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -3992,14 +3922,6 @@ "ieee754": "^1.2.1" } }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -4178,6 +4100,18 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4307,11 +4241,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -4392,29 +4321,6 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4533,11 +4439,6 @@ "is-glob": "^4.0.1" } }, - "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==" - }, "global-dirs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", @@ -4674,11 +4575,6 @@ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, "interfaces": { "version": "file:../interfaces", "requires": { @@ -4987,11 +4883,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -5021,6 +4912,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -5076,7 +4968,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "mkdirp": { "version": "0.5.5", @@ -5208,11 +5101,6 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, "nodemon": { "version": "2.0.15", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", @@ -5496,11 +5384,6 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, "registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -5567,6 +5450,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -6191,7 +6075,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yargs": { "version": "16.2.0", diff --git a/logger-service/package.json b/logger-service/package.json index 5ed7ac835a..88d48b4002 100644 --- a/logger-service/package.json +++ b/logger-service/package.json @@ -8,13 +8,13 @@ "@web-std/fetch": "3.0.0", "cors": "^2.8.5", "dotenv": "^16.0.0", - "fastmq": "^1.3.8", "fs-extra": "^10.0.0", "interfaces": "file:../interfaces", "module-alias": "^2.2.2", "mongodb": "^4.2.1", "reflect-metadata": "^0.1.13", - "typeorm": "^0.2.41" + "typeorm": "^0.2.41", + "common":"file:../common" }, "description": "", "devDependencies": { @@ -31,6 +31,7 @@ "main": "dist/index.js", "name": "logger-service", "scripts": { + "dev:docker": "nodemon .", "watch": "nodemon src/index.ts", "build": "tsc", "debug": "nodemon dist/index.js", @@ -38,5 +39,5 @@ "lint": "tslint --project .", "start": "node dist/index.js" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/logger-service/src/api/logger.service.ts b/logger-service/src/api/logger.service.ts index 760f7738c7..2278e12231 100644 --- a/logger-service/src/api/logger.service.ts +++ b/logger-service/src/api/logger.service.ts @@ -1,9 +1,11 @@ -import { ILog, IPageParameters, MessageAPI, MessageError, MessageResponse } from 'interfaces'; import { MongoRepository } from 'typeorm'; import { Log } from '@entity/log'; +import { MessageBrokerChannel, MessageResponse, MessageError } from 'common'; +import { MessageAPI, ILog, IGetLogsMessage, IGetLogsResponse, IGetLogAttributesMessage } from 'interfaces'; + export const loggerAPI = async function ( - channel: any, + channel: MessageBrokerChannel, logRepository: MongoRepository ): Promise { /** @@ -12,52 +14,51 @@ export const loggerAPI = async function ( * @param {Message} [payload] - Log message * */ - channel.response(MessageAPI.WRITE_LOG, async (msg, res) => { + channel.response(MessageAPI.WRITE_LOG, async (message) => { try { - const message = msg.payload as ILog; if (!message) { throw new Error("Log message is empty"); } await logRepository.save(message); - res.send(new MessageResponse(null)); + return new MessageResponse(true); } catch (e) { - res.send(new MessageError(e)); + return new MessageError(e); } }) /** - * Get logs. + * Get application logs. * - * @param {any} [payload.filters] - Response type - * @param {IPageParameters} [payload.pageParameters] - Page parameters + * @param {any} [msg.filters] - logs filter options + * @param {IPageParameters} [msg.pageParameters] - Page parameters * * @return {any} - Logs */ - channel.response(MessageAPI.GET_LOGS, async (msg, res) => { + channel.response(MessageAPI.GET_LOGS, async (msg) => { try { - const filters = msg.payload && msg.payload.filters || {}; + const filters = msg && msg.filters || {}; if (filters.datetime && filters.datetime.$gte && filters.datetime.$lt) { filters.datetime.$gte = new Date(filters.datetime.$gte); filters.datetime.$lt = new Date(filters.datetime.$lt); } - const pageParameters = msg.payload && msg.payload.pageParameters || {}; + const pageParameters = msg && msg.pageParameters || {}; const allFilters = { where: filters, order: { - datetime: msg.payload.sortDirection && msg.payload.sortDirection.toUpperCase() || "DESC" + datetime: msg.sortDirection && msg.sortDirection.toUpperCase() || "DESC" }, ...pageParameters }; - let logs = await logRepository.find(allFilters); - let totalCount = await logRepository.count(filters); - res.send(new MessageResponse({ + let logs = await logRepository.find(allFilters as any); + let totalCount = await logRepository.count(filters as any); + return new MessageResponse({ logs, totalCount - })); + }); } catch (e) { - res.send(new MessageError(e.toString())); + return new MessageError(e.toString()); } }) @@ -68,26 +69,26 @@ export const loggerAPI = async function ( * * @return {any} - Attributes */ - channel.response(MessageAPI.GET_ATTRIBUTES, async (msg, res) => { + channel.response(MessageAPI.GET_ATTRIBUTES, async (msg) => { try { - const nameFilter = `.*${msg.payload.name || ""}.*`; - const existingAttributes = msg.payload.existingAttributes || []; + const nameFilter = `.*${msg.name || ""}.*`; + const existingAttributes = msg.existingAttributes || []; let attrCursor = await logRepository.aggregate([ - { $project: { attributes : "$attributes" }}, - { $unwind: { path: "$attributes" }}, - { $match: { attributes: { $regex: nameFilter, $options: 'i'}}}, - { $match: { attributes: { $not: { $in: existingAttributes }}}}, - { $group: { _id: null, uniqueValues: { $addToSet: "$attributes" }}}, - { $unwind: { path: "$uniqueValues" }}, + { $project: { attributes: "$attributes" } }, + { $unwind: { path: "$attributes" } }, + { $match: { attributes: { $regex: nameFilter, $options: 'i' } } }, + { $match: { attributes: { $not: { $in: existingAttributes } } } }, + { $group: { _id: null, uniqueValues: { $addToSet: "$attributes" } } }, + { $unwind: { path: "$uniqueValues" } }, { $limit: 20 }, - { $group: { _id: null, uniqueValues: { $addToSet: "$uniqueValues" }}} + { $group: { _id: null, uniqueValues: { $addToSet: "$uniqueValues" } } } ]); const attrObject = await attrCursor.next(); attrCursor.close(); - res.send(new MessageResponse(attrObject?.uniqueValues?.sort() || [])); + return new MessageResponse(attrObject?.uniqueValues?.sort() || []); } catch (e) { - res.send(new MessageError(e.toString())); + return new MessageError(e.toString()); } }) } diff --git a/logger-service/src/app.ts b/logger-service/src/app.ts index 9f23da71db..c48a4f6ce5 100644 --- a/logger-service/src/app.ts +++ b/logger-service/src/app.ts @@ -1,8 +1,9 @@ -import FastMQ from 'fastmq'; import { createConnection } from 'typeorm'; import { loggerAPI } from '@api/logger.service'; import { Log } from '@entity/log'; -import { ApplicationState, ApplicationStates } from 'interfaces'; +import { ApplicationState, MessageBrokerChannel } from 'common'; +import { ApplicationStates } from 'interfaces' + Promise.all([ createConnection({ @@ -19,10 +20,10 @@ Promise.all([ entitiesDir: 'dist/entity' } }), - FastMQ.Client.connect(process.env.SERVICE_CHANNEL, 7500, process.env.MQ_ADDRESS), + MessageBrokerChannel.connect('LOGGER_SERVICE'), ]).then(async values => { - const [db, channel] = values; - + const [db, mqConnection] = values; + const channel = new MessageBrokerChannel(mqConnection, 'logger-service') const state = new ApplicationState('LOGGER_SERVICE'); state.setChannel(channel); state.updateState(ApplicationStates.STARTED); @@ -32,5 +33,5 @@ Promise.all([ await loggerAPI(channel, logRepository); state.updateState(ApplicationStates.READY); - console.log('logger service started'); + console.log('logger service started', await state.getState()); }) diff --git a/logger-service/tsconfig.json b/logger-service/tsconfig.json index 4905dde411..f656f84026 100644 --- a/logger-service/tsconfig.json +++ b/logger-service/tsconfig.json @@ -11,6 +11,7 @@ "sourceMap": true, "outDir": "dist/", "esModuleInterop": true, + "skipLibCheck": true, "baseUrl": "./src", "paths": { "@entity/*": ["entity/*"], diff --git a/message-broker/.dockerignore b/message-broker/.dockerignore deleted file mode 100644 index 475c70bf49..0000000000 --- a/message-broker/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -npm-debug.log -dist \ No newline at end of file diff --git a/message-broker/Dockerfile b/message-broker/Dockerfile deleted file mode 100644 index 7f4d0f2d96..0000000000 --- a/message-broker/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:16 -ENV PLATFORM="docker" -#ENV NODE_ENV="production" - -WORKDIR /usr/message-broker -COPY ./message-broker/package*.json ./ -COPY ./message-broker/tsconfig.json ./ -RUN npm install -ADD ./message-broker/src ./src/. -RUN npm run build - -CMD npm start diff --git a/message-broker/package-lock.json b/message-broker/package-lock.json deleted file mode 100644 index ab7b4fd4de..0000000000 --- a/message-broker/package-lock.json +++ /dev/null @@ -1,4705 +0,0 @@ -{ - "name": "message-broker", - "version": "1.0.5", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "message-broker", - "version": "1.0.5", - "license": "Apache-2.0", - "dependencies": { - "express": "^4.17.1", - "fastmq": "^1.3.8" - }, - "devDependencies": { - "@types/express": "^4.17.13", - "@types/node": "^17.0.13", - "mocha-junit-reporter": "^2.0.2", - "nodemon": "^2.0.7", - "typescript": "^4.5.5" - } - }, - "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "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==", - "dev": true - }, - "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true - }, - "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==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true, - "peer": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, - "peer": true - }, - "node_modules/buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "dependencies": { - "int64-buffer": "^0.1.9" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/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/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "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/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "dependencies": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "peer": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "peer": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "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", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "peer": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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==" - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "peer": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "peer": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "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-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true, - "peer": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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, - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": 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.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dev": true, - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "peer": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha-junit-reporter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", - "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", - "dev": true, - "dependencies": { - "debug": "^2.2.0", - "md5": "^2.1.0", - "mkdirp": "~0.5.1", - "strip-ansi": "^6.0.1", - "xml": "^1.0.0" - }, - "peerDependencies": { - "mocha": ">=2.2.5" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "peer": true - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "peer": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node_modules/nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "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/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "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/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "peer": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "dependencies": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true, - "peer": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "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", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "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/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "peer": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true - }, - "@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==", - "dev": true - }, - "@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==", - "dev": true - }, - "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true, - "peer": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "peer": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "peer": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - } - }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, - "peer": true - }, - "buffer-plus": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/buffer-plus/-/buffer-plus-1.3.0.tgz", - "integrity": "sha512-m0BI8oostnCeKnEPtG4B2kXueZ8PB7TNsfuLoLzgCV1+ZlD3WBwKc14AoTWjopnA2nPQP/ARqAahuPHtm2OQFA==", - "requires": { - "int64-buffer": "^0.1.9" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "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, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.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" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "peer": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "peer": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "peer": true - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "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, - "requires": { - "once": "^1.4.0" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "peer": true - }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "peer": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "fastmq": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/fastmq/-/fastmq-1.3.8.tgz", - "integrity": "sha512-mdgojZrgLMS9am+TTGgP+9yMLninq5rE3Ht8EK90BWMvtVVxSgwss+UPsVCkGuyu+p2L94s9QbMmKhiNZ3kfIw==", - "requires": { - "@babel/runtime": "^7.3.4", - "bluebird": "^3.5.3", - "buffer-plus": "^1.1.1", - "double-ended-queue": "^2.1.0-0", - "eventemitter3": "^3.1.0", - "glob-to-regexp": "^0.4.0", - "is-regex": "^1.0.5", - "lodash": "^4.17.20", - "minimist": "^1.2.5", - "node-int64": "^0.4.0", - "semver": "^7.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "peer": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "peer": true - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "peer": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "peer": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "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==" - }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "peer": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "peer": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "peer": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - }, - "int64-buffer": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", - "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "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==", - "dev": true, - "peer": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "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, - "peer": true - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true, - "peer": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "peer": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "peer": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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, - "peer": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dev": true, - "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "peer": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "peer": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "peer": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true - } - } - }, - "mocha-junit-reporter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-2.0.2.tgz", - "integrity": "sha512-vYwWq5hh3v1lG0gdQCBxwNipBfvDiAM1PHroQRNp96+2l72e9wEUTw+mzoK+O0SudgfQ7WvTQZ9Nh3qkAYAjfg==", - "dev": true, - "requires": { - "debug": "^2.2.0", - "md5": "^2.1.0", - "mkdirp": "~0.5.1", - "strip-ansi": "^6.0.1", - "xml": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "peer": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "peer": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "peer": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "peer": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "peer": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "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, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } - }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "requires": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "peer": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "peer": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "peer": true - }, - "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, - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true - }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "peer": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, - "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true, - "peer": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "peer": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "peer": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "peer": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "peer": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "peer": true - } - } -} diff --git a/message-broker/package.json b/message-broker/package.json deleted file mode 100644 index d7bb9453d7..0000000000 --- a/message-broker/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "message-broker", - "description": "", - "main": "index.js", - "scripts": { - "dev": "tsc -w", - "start": "node dist/index.js", - "debug": "nodemon dist/index.js", - "build": "tsc" - }, - "author": "Envision Blockchain Solutions ", - "license": "Apache-2.0", - "dependencies": { - "express": "^4.17.1", - "fastmq": "^1.3.8" - }, - "devDependencies": { - "@types/express": "^4.17.13", - "@types/node": "^17.0.13", - "mocha-junit-reporter": "^2.0.2", - "nodemon": "^2.0.7", - "typescript": "^4.5.5" - }, - "version": "2.0.0" -} diff --git a/message-broker/src/index.ts b/message-broker/src/index.ts deleted file mode 100644 index 4e3501a144..0000000000 --- a/message-broker/src/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -import FastMQ from 'fastmq' -import express, {Request, Response} from 'express' - -const mqServer = FastMQ.Server.create('master', 7500, '0.0.0.0'); - -const PORT = process.env.PORT || 3003; - -// start server -export default Promise.all([ - mqServer.start() -]).then(async () => { - - const app = express(); - app.use(express.json()); - - const channel = await FastMQ.Client.connect('mrv-data', 7500, '127.0.0.1'); - - app.post('/mrv', async (req: Request, res: Response) => { - try { - await channel.request('guardian.*', 'mrv-data', req.body, 'json'); - res.sendStatus(200); - } catch (e) { - res.status(500).send(e.message); - } - }); - - app.listen(PORT, () => { - console.log('Message Broker server started', PORT); - }); -}); diff --git a/message-broker/tsconfig.tsbuildinfo b/message-broker/tsconfig.tsbuildinfo deleted file mode 100644 index 0f70225ca1..0000000000 --- a/message-broker/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"program":{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.esnext.intl.d.ts","../node_modules/reflect-metadata/index.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/globals.global.d.ts","../node_modules/@types/node/index.d.ts","../node_modules/@types/range-parser/index.d.ts","../node_modules/@types/qs/index.d.ts","../node_modules/@types/express-serve-static-core/index.d.ts","../node_modules/@types/mime/index.d.ts","../node_modules/@types/serve-static/index.d.ts","../node_modules/@types/connect/index.d.ts","../node_modules/@types/body-parser/index.d.ts","../node_modules/@types/express/index.d.ts","./src/index.ts","../node_modules/@types/asn1js/index.d.ts","../node_modules/@types/crypto-js/index.d.ts","../node_modules/@types/fs-extra/index.d.ts","../node_modules/@types/js-yaml/index.d.ts","../node_modules/@types/jsonwebtoken/index.d.ts","../node_modules/@types/long/index.d.ts","../node_modules/@types/utf8/index.d.ts","../node_modules/@types/ws/index.d.ts","../node_modules/@types/zen-observable/index.d.ts"],"fileInfos":[{"version":"aa9fb4c70f369237c2f45f9d969c9a59e0eae9a192962eb48581fe864aa609db","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84","e21c071ca3e1b4a815d5f04a7475adcaeea5d64367e840dd0154096d705c3940",{"version":"51b8b27c21c066bf877646e320bf6a722b80d1ade65e686923cd9d4494aef1ca","affectsGlobalScope":true},{"version":"43fb1d932e4966a39a41b464a12a81899d9ae5f2c829063f5571b6b87e6d2f9c","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"2c8c5ee58f30e7c944e04ab1fb5506fdbb4dd507c9efa6972cf4b91cec90c503","affectsGlobalScope":true},{"version":"2bb4b3927299434052b37851a47bf5c39764f2ba88a888a107b32262e9292b7c","affectsGlobalScope":true},{"version":"810627a82ac06fb5166da5ada4159c4ec11978dfbb0805fe804c86406dab8357","affectsGlobalScope":true},{"version":"62d80405c46c3f4c527ee657ae9d43fda65a0bf582292429aea1e69144a522a6","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"12a310447c5d23c7d0d5ca2af606e3bd08afda69100166730ab92c62999ebb9d","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"df9c8a72ca8b0ed62f5470b41208a0587f0f73f0a7db28e5a1272cf92537518e","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"93544ca2f26a48716c1b6c5091842cad63129daac422dfa4bc52460465f22bb1","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"1b3fe904465430e030c93239a348f05e1be80640d91f2f004c3512c2c2c89f34","affectsGlobalScope":true},{"version":"7435b75fdf3509622e79622dbe5091cf4b09688410ee2034e4fc17d0c99d0862","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"9f1817f7c3f02f6d56e0f403b927e90bb133f371dcebc36fa7d6d208ef6899da","affectsGlobalScope":true},{"version":"4632665b87204bb1caa8b44d165bce0c50dfab177df5b561b345a567cabacf9a","affectsGlobalScope":true},{"version":"8d6d51a5118d000ed3bfe6e1dd1335bebfff3fef23cd2af2f84a24d30f90cc90","affectsGlobalScope":true},"0d5a2ee1fdfa82740e0103389b9efd6bfe145a20018a2da3c02b89666181f4d9","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"92d63add669d18ebc349efbacd88966d6f2ccdddfb1b880b2db98ae3aa7bf7c4","affectsGlobalScope":true},"ccc94049a9841fe47abe5baef6be9a38fc6228807974ae675fb15dc22531b4be",{"version":"9acfe4d1ff027015151ce81d60797b04b52bffe97ad8310bb0ec2e8fd61e1303","affectsGlobalScope":true},"43978f18d1165eea81040bc9bfac1a551717f5cc9bd0f13b31bf490c5fcdc75f","afc6e96061af46bcff47246158caee7e056f5288783f2d83d6858cd25be1c565",{"version":"c3ad91d23259b68e10a9bef08c5f9fa1d19f27ef740ac9af98ed226b030c09c6","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","57a558a99ab24fdff45a2c2db0c34285de2dcbc66149d9a3d83fcde844426e37","260aad3a6bd3fc510b7f97cfb05859bfc045ce185f8c2b4d73ddb9c43b0eb3c0","cb428529763c6c8e38e42db2a39f333ffcc6d3aab396b24ac84b22da752c1de0","ad4b60488fb1e562bf375dac9299815f7028bf667d9b5887b2d01d501b7d1ddd","246341c3a7a2638cf830d690e69de1e6085a102c6a30596435b050e6ac86c11a","6972fca26f6e9bd56197568d4379f99071a90766e06b4fcb5920a0130a9202be",{"version":"4a2628e95962c8ab756121faa3ac2ed348112ff7a87b5c286dd2cc3326546b4c","affectsGlobalScope":true},"fd5d2f531376b1e84df315df0fe724445353a0ae2e2c4de7bae01e24c6c2047a","84214d474bed6e36b7608ba8a39d463ff90061b8af47cbd1a8f7ecb775e21fac","944660c079e97f62f513c33ec64cebc44154374053d3a9adb04bf02f67ee1066","b287b810b5035d5685f1df6e1e418f1ca452a3ed4f59fd5cc081dbf2045f0d9b","4b9a003b5c556c96784132945bb41c655ea11273b1917f5c8d0c154dd5fd20dd","62a00c9cc0c78d9f282dcd7b0a7776aefe220106c3bc327e259e5f6484c6f556",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"f3e8bcce378a26bc672fce0ec05affabbbbfa18493b76f24c39136dea87100d0","abc1c425b2ad6720433f40f1877abfa4223f0f3dd486c9c28c492179ca183cb6","cd4854d38f4eb5592afd98ab95ca17389a7dfe38013d9079e802d739bdbcc939","94eed4cc2f5f658d5e229ff1ccd38860bddf4233e347bf78edd2154dee1f2b99",{"version":"e51bee3200733b1f58818b5a9ea90fcd61c5b8afa3a0378391991f3696826a65","affectsGlobalScope":true},"9f1069b9e2c051737b1f9b4f1baf50e4a63385a6a89c32235549ae87fc3d5492","ee18f2da7a037c6ceeb112a084e485aead9ea166980bf433474559eac1b46553","e70339a3d63f806c43f24250c42aa0000093923457b0ed7dfc10e0ac910ebca9","0acbf26bf958f9e80c1ffa587b74749d2697b75b484062d36e103c137c562bc3","d7838022c7dab596357a9604b9c6adffe37dc34085ce0779c958ce9545bd7139","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff",{"version":"806ef4cac3b3d9fa4a48d849c8e084d7c72fcd7b16d76e06049a9ed742ff79c0","affectsGlobalScope":true},"a279435e7813d1f061c0cab6ab77b1b9377e8d96851e5ed4a76a1ce6eb6e628f","c33a6ea7147af60d8e98f1ac127047f4b0d4e2ce28b8f08ff3de07ca7cc00637",{"version":"b42b47e17b8ece2424ae8039feb944c2e3ba4b262986aebd582e51efbdca93dc","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","2408611d9b4146e35d1dbd1f443ccd8e187c74614a54b80300728277529dbf11","998a3de5237518c0b3ac00a11b3b4417affb008aa20aedee52f3fdae3cb86151","ad41008ffe077206e1811fc873f4d9005b5fd7f6ab52bb6118fef600815a5cb4","b810390059fc34122556c644f586e7a2b4598ded8afe5ba70bb82fc2e50577b1","ba9de5c5823e06ee3314f959c138cdaf4477d3a1a0769f0d24e62911020e8088","c3db860bcaaaeb3bbc23f353bbda1f8ab82756c8d5e973bebb3953cb09ea68f2","235a53595bd20b0b0eeb1a29cb2887c67c48375e92f03749b2488fbd46d0b1a0","bc09393cd4cd13f69cf1366d4236fbae5359bb550f0de4e15767e9a91d63dfb1","9c266243b01545e11d2733a55ad02b4c00ecdbda99c561cd1674f96e89cdc958","c71155c05fc76ff948a4759abc1cb9feec036509f500174bc18dad4c7827a60c",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"893f4b8552c248f6542174b53d1519f739b20428c970dda89cd90485dab059d0","16d51f964ec125ad2024cf03f0af444b3bc3ec3614d9345cc54d09bab45c9a4c","ba601641fac98c229ccd4a303f747de376d761babb33229bb7153bed9356c9cc",{"version":"61b60d145059c3c8e3c7b484713191b6d0b70999bcb11f2b26286b15926a2b5f","affectsGlobalScope":true},"84e3bbd6f80983d468260fdbfeeb431cc81f7ea98d284d836e4d168e36875e86","0b85cb069d0e427ba946e5eb2d86ef65ffd19867042810516d16919f6c1a5aec","6d829824ead8999f87b6df21200df3c6150391b894b4e80662caa462bd48d073","65cfd1c0bc729fbc2b49fe66bc5ebddba5aa3a978c748e1d2e0d07f502238ce2","15c88bfd1b8dc7231ff828ae8df5d955bae5ebca4cf2bcb417af5821e52299ae","30c2d34304b4074602e36a15b46844bb93aefb6b539aa616c24e754a552dbcc2","c53cdb0195a9103489a97d79baf26c1d8d4e695476be311a932b54a68363cbae",{"version":"070fafc332546049324c5eb0559b40974f700aa78eee7a12d1486035baa39558","affectsGlobalScope":true},"ed19da84b7dbf00952ad0b98ce5c194f1903bcf7c94d8103e8e0d63b271543ae","5b89c37ff5dfea00195f8ea5e6fc8e086be68613297fc8152c08900a1d1fdb83","7aa2c4361d1f3243c262813fec18366e89578c527f44b1ec60fdc8fc7977d551","e8465811693dfe4e96ef2b3dffda539d6edfe896961b7af37b44db2c0e48532b","ceffc958ebea94978cde2ad88e75fcdf3f89556ea4eafdc03fc7e2aece9bae77","bc81aff061c53a7140270555f4b22da4ecfe8601e8027cf5aa175fbdc7927c31",{"version":"09bba86d90385c19f2b69c0bf72d447ef6e5738964e3a344cb1f9e0270632be8","affectsGlobalScope":true}],"options":{"composite":true,"declaration":true,"declarationMap":true,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"inlineSourceMap":true,"module":1,"outDir":"./dist","rootDir":"./src","target":2},"fileIdsList":[[39,83,98],[83],[58,83,90,96],[58,83,90],[55,58,83,90,91,92],[83,92,93,95,97],[56,83,90],[83,90],[40,83],[43,83],[44,49,83],[45,55,56,63,72,82,83],[45,46,55,63,83],[47,83],[48,49,56,64,83],[49,72,79,83],[50,52,55,63,83],[51,83],[52,53,83],[54,55,83],[55,83],[55,56,57,72,82,83],[55,56,57,72,83],[58,63,72,82,83],[55,56,58,59,63,72,79,82,83],[58,60,72,79,82,83],[40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89],[55,61,83],[62,82,83],[52,55,63,72,83],[64,83],[65,83],[43,66,83],[67,81,83,87],[68,83],[69,83],[55,70,83],[70,71,83,85],[55,72,73,74,83],[72,74,83],[72,73,83],[75,83],[76,83],[55,77,78,83],[77,78,83],[49,63,79,83],[80,83],[63,81,83],[44,58,69,82,83],[49,83],[72,83,84],[83,85],[83,86],[44,49,55,57,66,72,82,83,85,87],[72,83,88],[58,83,90,94],[55,58,60,63,72,79,82,83,88,90]],"referencedMap":[[99,1],[100,2],[97,3],[96,4],[101,2],[93,5],[98,6],[102,7],[103,2],[104,8],[105,2],[94,2],[40,9],[41,9],[43,10],[44,11],[45,12],[46,13],[47,14],[48,15],[49,16],[50,17],[51,18],[52,19],[53,19],[54,20],[55,21],[56,22],[57,23],[42,2],[89,2],[58,24],[59,25],[60,26],[90,27],[61,28],[62,29],[63,30],[64,31],[65,32],[66,33],[67,34],[68,35],[69,36],[70,37],[71,38],[72,39],[74,40],[73,41],[75,42],[76,43],[77,44],[78,45],[79,46],[80,47],[81,48],[82,49],[83,50],[84,51],[85,52],[86,53],[87,54],[88,55],[92,2],[91,2],[95,56],[106,2],[107,57],[108,2],[39,2],[9,2],[8,2],[2,2],[10,2],[11,2],[12,2],[13,2],[14,2],[15,2],[16,2],[17,2],[3,2],[4,2],[21,2],[18,2],[19,2],[20,2],[22,2],[23,2],[24,2],[5,2],[25,2],[26,2],[27,2],[28,2],[6,2],[29,2],[30,2],[31,2],[32,2],[7,2],[37,2],[33,2],[34,2],[35,2],[36,2],[1,2],[38,2]],"exportedModulesMap":[[99,1],[100,2],[97,3],[96,4],[101,2],[93,5],[98,6],[102,7],[103,2],[104,8],[105,2],[94,2],[40,9],[41,9],[43,10],[44,11],[45,12],[46,13],[47,14],[48,15],[49,16],[50,17],[51,18],[52,19],[53,19],[54,20],[55,21],[56,22],[57,23],[42,2],[89,2],[58,24],[59,25],[60,26],[90,27],[61,28],[62,29],[63,30],[64,31],[65,32],[66,33],[67,34],[68,35],[69,36],[70,37],[71,38],[72,39],[74,40],[73,41],[75,42],[76,43],[77,44],[78,45],[79,46],[80,47],[81,48],[82,49],[83,50],[84,51],[85,52],[86,53],[87,54],[88,55],[92,2],[91,2],[95,56],[106,2],[107,57],[108,2],[39,2],[9,2],[8,2],[2,2],[10,2],[11,2],[12,2],[13,2],[14,2],[15,2],[16,2],[17,2],[3,2],[4,2],[21,2],[18,2],[19,2],[20,2],[22,2],[23,2],[24,2],[5,2],[25,2],[26,2],[27,2],[28,2],[6,2],[29,2],[30,2],[31,2],[32,2],[7,2],[37,2],[33,2],[34,2],[35,2],[36,2],[1,2],[38,2]],"semanticDiagnosticsPerFile":[99,100,97,96,101,93,98,102,103,104,105,94,40,41,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,42,89,58,59,60,90,61,62,63,64,65,66,67,68,69,70,71,72,74,73,75,76,77,78,79,80,81,82,83,84,85,86,87,88,92,91,95,106,107,108,39,9,8,2,10,11,12,13,14,15,16,17,3,4,21,18,19,20,22,23,24,5,25,26,27,28,6,29,30,31,32,7,37,33,34,35,36,1,38]},"version":"4.4.3"} \ No newline at end of file diff --git a/mrv-sender/Dockerfile b/mrv-sender/Dockerfile index 9738364f74..bad634aa7b 100644 --- a/mrv-sender/Dockerfile +++ b/mrv-sender/Dockerfile @@ -9,6 +9,13 @@ RUN npm install ADD ./interfaces/src ./src/. RUN npm run build +WORKDIR /usr/common +COPY ./common/package*.json ./ +COPY ./common/tsconfig.json ./ +RUN npm install +ADD ./common/src ./src/. +RUN npm run build + WORKDIR /usr/mrv-sender COPY ./mrv-sender/package*.json ./ COPY ./mrv-sender/tsconfig.json ./ diff --git a/mrv-sender/nodemon.json b/mrv-sender/nodemon.json new file mode 100644 index 0000000000..8b879fd87b --- /dev/null +++ b/mrv-sender/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["./dist", "../interfaces/dist", "../common/dist", "../logger-helper/dist"], + "delay": 2500, + "ext": "ts, js", + "exec": "node dist/index.js" +} diff --git a/mrv-sender/package-lock.json b/mrv-sender/package-lock.json index 59362a1c42..f50970ae7b 100644 --- a/mrv-sender/package-lock.json +++ b/mrv-sender/package-lock.json @@ -1,12 +1,12 @@ { "name": "mrv-sender", - "version": "1.0.5", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mrv-sender", - "version": "1.0.5", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { "@transmute/credentials-context": "0.7.0-unstable.40", @@ -17,6 +17,7 @@ "@transmute/security-context": "0.7.0-unstable.40", "@transmute/vc.js": "0.7.0-unstable.40", "axios": "^0.26.1", + "common": "file:../common", "express": "^4.17.3", "jose": "4.3.8" }, @@ -26,6 +27,21 @@ "typescript": "^4.6.3" } }, + "../common": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "interfaces": "file:../interfaces", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/node": "^17.0.13", + "mocha-junit-reporter": "^2.0.2", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "../vc-modules": { "version": "1.0.5", "extraneous": true, @@ -1160,6 +1176,10 @@ "node": ">=4.0.0" } }, + "node_modules/common": { + "resolved": "../common", + "link": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4892,6 +4912,18 @@ "typical": "^2.6.1" } }, + "common": { + "version": "file:../common", + "requires": { + "@types/node": "^17.0.13", + "interfaces": "file:../interfaces", + "mocha-junit-reporter": "^2.0.2", + "nats": "^2.6.1", + "reflect-metadata": "^0.1.13", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", diff --git a/mrv-sender/package.json b/mrv-sender/package.json index 0758399d9a..4bf1de888f 100644 --- a/mrv-sender/package.json +++ b/mrv-sender/package.json @@ -10,7 +10,8 @@ "@transmute/vc.js": "0.7.0-unstable.40", "axios": "^0.26.1", "express": "^4.17.3", - "jose": "4.3.8" + "jose": "4.3.8", + "common":"file:../common" }, "description": "", "devDependencies": { @@ -25,7 +26,8 @@ "build": "tsc", "debug": "nodemon dist/index.js", "dev": "tsc -w", + "dev:docker": "nodemon .", "start": "node dist/index.js" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/topic-viewer/package-lock.json b/topic-viewer/package-lock.json index f2608f464e..6f0d20574f 100644 --- a/topic-viewer/package-lock.json +++ b/topic-viewer/package-lock.json @@ -1,15 +1,14 @@ { - "name": "mrv-sender", - "version": "1.2.1", + "name": "topic-viewer", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "mrv-sender", - "version": "1.2.1", + "name": "topic-viewer", + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "axios": "^0.26.1", "express": "^4.17.3" }, "devDependencies": { @@ -184,14 +183,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -731,25 +722,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2078,14 +2050,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "requires": { - "follow-redirects": "^1.14.8" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2522,11 +2486,6 @@ } } }, - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", diff --git a/topic-viewer/package.json b/topic-viewer/package.json index ac3d4ac603..a0ab2c8f15 100644 --- a/topic-viewer/package.json +++ b/topic-viewer/package.json @@ -13,10 +13,11 @@ "main": "dist/index.js", "name": "topic-viewer", "scripts": { + "dev:docker": "nodemon src/index.ts", "build": "tsc", "debug": "nodemon dist/index.js", "dev": "tsc -w", "start": "node dist/index.js" }, - "version": "2.0.0" + "version": "2.1.0" } diff --git a/web-proxy/Dockerfile.ci b/web-proxy/Dockerfile.ci new file mode 100644 index 0000000000..04bb670cfd --- /dev/null +++ b/web-proxy/Dockerfile.ci @@ -0,0 +1,18 @@ +FROM node:16 as frontendBuilder +WORKDIR /usr/local/interfaces +COPY ./interfaces/package*.json /usr/local/interfaces/ +COPY ./interfaces/tsconfig.json /usr/local/interfaces/ +RUN npm install +ADD ./interfaces/src/ /usr/local/interfaces/src/. +RUN npm run build +WORKDIR /usr/local/frontend +COPY ./frontend/. /usr/local/frontend +RUN npm install +RUN npm run build + +FROM nginx:latest +ENV PLATFORM="docker" +COPY ./web-proxy/configs/image.conf /etc/nginx/conf.d/default.conf +COPY --from=frontendBuilder /usr/local/frontend/dist/guardian /usr/share/nginx/html + +EXPOSE 80 diff --git a/web-proxy/configs/image.conf b/web-proxy/configs/image.conf new file mode 100644 index 0000000000..c5b4245725 --- /dev/null +++ b/web-proxy/configs/image.conf @@ -0,0 +1,66 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + #access_log /var/log/nginx/host.access.log main; + + location /ws/ { + proxy_pass http://$ENV{"GATEWAY_HOST"}:$ENV{"GATEWAY_PORT"}; + proxy_set_header Host $host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 120s; + } + + location /api/v1/ { + proxy_pass http://$ENV{"GATEWAY_HOST"}:$ENV{"GATEWAY_PORT"}/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Surrogate-Control no-store; + proxy_set_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate"; + proxy_set_header Pragma no-cache; + proxy_set_header Expires 0; + proxy_redirect off; + } + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # proxy the PHP scripts to Apache listening on 127.0.0.1:80 + # + #location ~ \.php$ { + # proxy_pass http://127.0.0.1; + #} + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # + #location ~ \.php$ { + # root html; + # fastcgi_pass 127.0.0.1:9000; + # fastcgi_index index.php; + # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; + # include fastcgi_params; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +} diff --git a/web-proxy/configs/local.conf b/web-proxy/configs/local.conf new file mode 100644 index 0000000000..dfeef9aca2 --- /dev/null +++ b/web-proxy/configs/local.conf @@ -0,0 +1,97 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + #access_log /var/log/nginx/host.access.log main; + + location /ws/ { + proxy_pass http://api-gateway:3002; + proxy_set_header Host $host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 120s; + } + + location /api/v1/ { + proxy_pass http://api-gateway:3002/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Surrogate-Control no-store; + proxy_set_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate"; + proxy_set_header Pragma no-cache; + proxy_set_header Expires 0; + proxy_redirect off; + } + + location /mrv-sender/ { + proxy_pass http://mrv-sender:3005/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } + + location /topic-viewer/ { + proxy_pass http://topic-viewer:3006/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } + + location /api-docs/v1/ { + proxy_pass http://api-docs:3001/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } + + location / { + proxy_pass http://front-end:4200/; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # proxy the PHP scripts to Apache listening on 127.0.0.1:80 + # + #location ~ \.php$ { + # proxy_pass http://127.0.0.1; + #} + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # + #location ~ \.php$ { + # root html; + # fastcgi_pass 127.0.0.1:9000; + # fastcgi_index index.php; + # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; + # include fastcgi_params; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +} \ No newline at end of file